-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
42dc44a
commit d053308
Showing
25 changed files
with
697 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.env | ||
node_modules/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
DB_INSTANCES='mysql01,cego_test_db' | ||
MYSQL01_HOST=127.0.0.1 | ||
MYSQL01_PORT=3306 | ||
MYSQL01_USER=root | ||
|
||
CEGO_TEST_DB_HOST=127.0.0.1 | ||
CEGO_TEST_DB_PORT=3306 | ||
CEGO_TEST_DB_USER=root | ||
CEGO_TEST_DB_DATABASE=testdb |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"extends": "next/core-web-vitals" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
.yarn/install-state.gz | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
# IDE | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"trailingComma": "es5", | ||
"tabWidth": 4, | ||
"semi": false, | ||
"singleQuote": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# use the official Bun image | ||
# see all versions at https://hub.docker.com/r/oven/bun/tags | ||
FROM oven/bun:1.1 as base | ||
WORKDIR /usr/src/app | ||
|
||
# install dependencies into temp directory | ||
# this will cache them and speed up future builds | ||
FROM base AS install | ||
RUN mkdir -p /temp/dev | ||
COPY package.json bun.lockb /temp/dev/ | ||
RUN cd /temp/dev && bun install --frozen-lockfile | ||
|
||
# install with --production (exclude devDependencies) | ||
RUN mkdir -p /temp/prod | ||
COPY package.json bun.lockb /temp/prod/ | ||
RUN cd /temp/prod && bun install --frozen-lockfile --production | ||
|
||
# copy node_modules from temp directory | ||
# then copy all (non-ignored) project files into the image | ||
FROM base AS prerelease | ||
COPY --from=install /temp/dev/node_modules node_modules | ||
COPY . . | ||
|
||
ENV NODE_ENV=production | ||
RUN bun run build | ||
|
||
CMD ["bun", "run", "start"] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,27 @@ | ||
# mysql-admin | ||
Show, Edit or Create PROCESSLIST, SLAVE resources | ||
This is a small Next.js app for viewing and killing active processes on multiple MariaDB instances. | ||
|
||
### Features | ||
- See all active processes, joined with any open transactions. | ||
- Mark long-running open transactions with red. | ||
- Sorted by transaction time desc, then by process time desc. | ||
- Kill a process with two clicks. | ||
|
||
### Deployment | ||
TODO: Link to dockerhub | ||
|
||
The image requires the following environment variables: | ||
- `DB_INSTANCES` - A comma separated list of MariaDB instances to connect to. | ||
|
||
For each instance, the following environment variables are required: | ||
- `{DB_INSTANCE_NAME}_HOST` - The hostname of the MariaDB instance. | ||
- `{DB_INSTANCE_NAME}_PORT` - The port of the MariaDB instance. | ||
- `{DB_INSTANCE_NAME}_USER` - The username to connect to the MariaDB instance. | ||
|
||
And optionally | ||
- `{DB_INSTANCE_NAME}_PASSWORD` - The password to connect to the MariaDB instance. | ||
- `{DB_INSTANCE_NAME}_DATABASE` - The database to connect to on the MariaDB instance. | ||
|
||
Example environment variables can be found [here](.env). | ||
|
||
### Development | ||
To start a dev server, run `bun start dev` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/** @type {import('next').NextConfig} */ | ||
const nextConfig = { | ||
reactStrictMode: true, | ||
} | ||
|
||
export default nextConfig |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "mariadb-process-web", | ||
"version": "0.1.0", | ||
"private": true, | ||
"scripts": { | ||
"dev": "next dev", | ||
"build": "next build", | ||
"start": "next start --port 80", | ||
"lint": "next lint", | ||
"prettier": "prettier --write ." | ||
}, | ||
"dependencies": { | ||
"dotenv": "^16.4.5", | ||
"mysql2": "^3.9.4", | ||
"next": "14.1.4", | ||
"react": "^18", | ||
"react-dom": "^18" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.12.7", | ||
"@types/react": "^18", | ||
"@types/react-dom": "^18", | ||
"autoprefixer": "^10.0.1", | ||
"daisyui": "^4.10.1", | ||
"eslint": "^8", | ||
"eslint-config-next": "14.1.4", | ||
"postcss": "^8", | ||
"prettier": "^3.2.5", | ||
"tailwindcss": "^3.3.0", | ||
"typescript": "^5" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import assert from 'assert' | ||
|
||
export type Instance = { | ||
host: string | ||
port: number | ||
user: string | ||
password: string | undefined | ||
database: string | undefined | ||
} | ||
|
||
export type Instances = { [key: string]: Instance } | ||
|
||
export type Config = { | ||
instances: Instances | ||
} | ||
|
||
export const getConfig = (): Config => { | ||
// Load database instances from the environment variables | ||
const dbInstancesEnv = process.env.DB_INSTANCES | ||
assert(dbInstancesEnv, 'DB_INSTANCES is required') | ||
const dbInstances = dbInstancesEnv.split(',') | ||
|
||
// For each db instance, load the host, port, user, password, and optional database | ||
const instances: Instances = dbInstances.reduce((acc, dbInstance) => { | ||
const dbInstanceUpper = dbInstance.toUpperCase() | ||
const dbInstanceHostEnv = process.env[`${dbInstanceUpper}_HOST`] | ||
assert(dbInstanceHostEnv, `${dbInstanceUpper}_HOST is required`) | ||
const dbInstanceHost = dbInstanceHostEnv | ||
|
||
const dbInstancePortEnv = process.env[`${dbInstanceUpper}_PORT`] | ||
assert(dbInstancePortEnv, `${dbInstanceUpper}_PORT is required`) | ||
|
||
const dbInstancePort = parseInt(dbInstancePortEnv) | ||
assert(dbInstancePort, `${dbInstanceUpper}_PORT must be a number`) | ||
|
||
const dbInstanceUserEnv = process.env[`${dbInstanceUpper}_USER`] | ||
assert(dbInstanceUserEnv, `${dbInstanceUpper}_USER is required`) | ||
|
||
const dbInstanceUser = dbInstanceUserEnv | ||
|
||
const dbInstancePassword = process.env[`${dbInstanceUpper}_PASSWORD`] | ||
|
||
const dbInstanceDatabase = process.env[`${dbInstanceUpper}_DATABASE`] | ||
|
||
acc[dbInstance] = { | ||
host: dbInstanceHost, | ||
port: dbInstancePort, | ||
user: dbInstanceUser, | ||
password: dbInstancePassword, | ||
database: dbInstanceDatabase, | ||
} | ||
|
||
return acc | ||
}, {} as Instances) | ||
|
||
return { | ||
instances, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
import '@/styles/globals.css' | ||
import type { AppProps } from 'next/app' | ||
|
||
export default function App({ Component, pageProps }: AppProps) { | ||
return <Component {...pageProps} /> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { Html, Head, Main, NextScript } from 'next/document' | ||
|
||
export default function Document() { | ||
return ( | ||
<Html lang="en"> | ||
<Head /> | ||
<body> | ||
<Main /> | ||
<NextScript /> | ||
</body> | ||
</Html> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction | ||
import type { NextApiRequest, NextApiResponse } from 'next' | ||
|
||
type Data = { | ||
name: string | ||
} | ||
|
||
export default function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse<Data> | ||
) { | ||
res.status(200).json({ name: 'John Doe' }) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// Given the id in post body, kill the mysql process with that id | ||
|
||
import { NextApiRequest, NextApiResponse } from 'next' | ||
import { getConfig } from '@/lib/config' | ||
import mysql from 'mysql2/promise' | ||
|
||
export default async function handler( | ||
req: NextApiRequest, | ||
res: NextApiResponse | ||
) { | ||
if (req.method === 'POST') { | ||
const { id, instance } = req.body | ||
if (!id) { | ||
return res.status(400).json({ error: 'id is required' }) | ||
} | ||
|
||
if (!instance) { | ||
return res.status(400).json({ error: 'instance is required' }) | ||
} | ||
|
||
const dbConfig = getConfig().instances[instance] | ||
|
||
if (!dbConfig) { | ||
return res.status(400).json({ error: 'instance not found' }) | ||
} | ||
|
||
// Kill the mysql process with the id | ||
// Use the id to kill the mysql process | ||
// res.status(200).json({ name: 'John Doe' }); | ||
const conn = await mysql.createConnection(dbConfig) | ||
await conn.query(`KILL ?`, [id]) | ||
res.status(200).json({ id }) | ||
} else { | ||
res.setHeader('Allow', ['POST']) | ||
res.status(405).end(`Method ${req.method} Not Allowed`) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { GetServerSideProps, InferGetServerSidePropsType } from 'next' | ||
import { Config, getConfig } from '@/lib/config' | ||
|
||
type Repo = { | ||
instances: string[] | ||
} | ||
|
||
export const getServerSideProps = (async () => { | ||
// Load available instances | ||
|
||
const repo: Repo = { instances: Object.keys(getConfig().instances) } | ||
// Pass data to the page via props | ||
return { props: { repo } } | ||
}) satisfies GetServerSideProps<{ repo: Repo }> | ||
|
||
export default function Home({ | ||
repo, | ||
}: InferGetServerSidePropsType<typeof getServerSideProps>) { | ||
return ( | ||
<main> | ||
<div className="text-xl breadcrumbs"> | ||
<ul> | ||
<li> | ||
<a>Instance Selector</a> | ||
</li> | ||
</ul> | ||
</div> | ||
<ul> | ||
{repo.instances.map((instance) => ( | ||
<li key={instance}> | ||
<a href={`/instance/${instance}`}>{instance}</a> | ||
</li> | ||
))} | ||
</ul> | ||
</main> | ||
) | ||
} |
Oops, something went wrong.