-
Notifications
You must be signed in to change notification settings - Fork 102
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Use chrome containers instead of chrome build repo.
- Loading branch information
1 parent
69399c1
commit 10f4e1f
Showing
9 changed files
with
583 additions
and
171 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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
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
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
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
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,166 @@ | ||
import axios from 'axios'; | ||
import path from 'path'; | ||
import fs from 'fs'; | ||
import { execSync, spawn } from 'child_process'; | ||
import { load } from 'js-yaml'; | ||
import { LogType, fecLogger } from '@redhat-cloud-services/frontend-components-config-utilities'; | ||
import waitOn from 'wait-on'; | ||
|
||
const REPO_OWNER = 'RedHatInsights'; | ||
const REPO_NAME = 'insights-chrome'; | ||
const CONTAINER_PORT = 8000; | ||
const CONTAINER_NAME = 'fec-chrome-local'; | ||
const IMAGE_REPO = 'quay.io/cloudservices/insights-chrome-frontend'; | ||
|
||
type ContainerRuntime = 'docker' | 'podman'; | ||
let execBin: ContainerRuntime | undefined = undefined; | ||
|
||
const chromeDeploymentConfig = { | ||
repo: 'git@gitlab.cee.redhat.com:service/app-interface.git', | ||
deployFile: 'data/services/insights/frontend-base/deploy.yml', | ||
tarTarget: path.resolve(__dirname, 'chrome-deploy/'), | ||
}; | ||
|
||
const checkoutCommand = `git archive --remote=${chromeDeploymentConfig.repo} HEAD ${chromeDeploymentConfig.deployFile} | tar xvf - -C ${chromeDeploymentConfig.tarTarget}`; | ||
|
||
function checkContainerRuntime(): ContainerRuntime { | ||
try { | ||
if (execSync('which podman').toString().trim().length > 0) { | ||
return 'podman'; | ||
} | ||
if (execSync('which docker').toString().trim().length > 0) { | ||
return 'docker'; | ||
} | ||
} catch (error) { | ||
throw new Error('No container runtime found'); | ||
} | ||
|
||
throw new Error('No container runtime found'); | ||
} | ||
|
||
async function getLatestCommits(): Promise<string> { | ||
const { data } = await axios.get(`https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/commits`, { | ||
headers: { | ||
Accept: 'application/vnd.github+json', | ||
'X-GitHub-Api-Version': '2022-11-28', | ||
}, | ||
params: { | ||
per_page: 1, | ||
}, | ||
}); | ||
if (data.length === 0) { | ||
throw new Error('No commits for chrome found!'); | ||
} | ||
|
||
const { sha } = data[0]; | ||
return sha.substring(0, 7); | ||
} | ||
|
||
type Deployment = { | ||
resourceTemplates: { | ||
name: string; | ||
targets: { | ||
ref: string; | ||
namespace: { | ||
$ref: string; | ||
}; | ||
}[]; | ||
}[]; | ||
}; | ||
|
||
async function getProdRelease() { | ||
try { | ||
if (!fs.existsSync(chromeDeploymentConfig.tarTarget)) { | ||
fs.mkdirSync(chromeDeploymentConfig.tarTarget); | ||
} | ||
execSync(checkoutCommand, { | ||
stdio: 'inherit', | ||
}); | ||
|
||
const deployment = load( | ||
fs.readFileSync(path.join(chromeDeploymentConfig.tarTarget, chromeDeploymentConfig.deployFile), { | ||
encoding: 'utf-8', | ||
}) | ||
) as Deployment; | ||
const chromeProd = deployment.resourceTemplates | ||
.find((template) => { | ||
return template.name === 'insights-chrome'; | ||
}) | ||
?.targets.find((target) => { | ||
return target.namespace.$ref.includes('prod-frontends'); | ||
}); | ||
if (!chromeProd) { | ||
throw new Error('Unable to find chrome prod deployment configuration.'); | ||
} | ||
|
||
return chromeProd.ref.substring(0, 7); | ||
} catch (error) { | ||
fecLogger(LogType.error, error); | ||
fecLogger(LogType.warn, 'Unable to find chrome prod deployment! Falling back to latest image.'); | ||
return getLatestCommits(); | ||
} | ||
} | ||
|
||
function pullImage(tag: string) { | ||
execSync(`${execBin} pull ${IMAGE_REPO}:${tag}`, { | ||
stdio: 'inherit', | ||
}); | ||
} | ||
|
||
async function startServer(tag: string, serverPort: number) { | ||
return new Promise<void>((resolve, reject) => { | ||
try { | ||
execSync(`${execBin} stop ${CONTAINER_NAME}`, { | ||
stdio: 'inherit', | ||
}); | ||
execSync(`${execBin} rm ${CONTAINER_NAME}`, { | ||
stdio: 'inherit', | ||
}); | ||
} catch (error) { | ||
fecLogger(LogType.info, 'No existing chrome container found'); | ||
} | ||
const runCommand = `${execBin} run -p ${serverPort}:${CONTAINER_PORT} --name ${CONTAINER_NAME} ${IMAGE_REPO}:${tag}`; | ||
const child = spawn(runCommand, [], { | ||
stdio: 'ignore', | ||
shell: true, | ||
}); | ||
child.stderr?.on('data', (data) => { | ||
reject(data.toString()); | ||
}); | ||
child.on('exit', () => { | ||
return reject(`Chrome server stopped unexpectedly! The server port ${serverPort} is already in use!`); | ||
}); | ||
}); | ||
} | ||
|
||
function copyIndex(path: string, isPreview = false) { | ||
const copyCommand = `${execBin} cp ${CONTAINER_NAME}:/opt/app-root/src/build/${isPreview ? 'preview' : 'stable'}/index.html ${path}`; | ||
execSync(copyCommand, { | ||
stdio: 'inherit', | ||
}); | ||
} | ||
|
||
async function serveChrome(distPath: string, host: string, onError: (error: Error) => void, isProd = false, isPreview = false, serverPort = 9999) { | ||
if (!distPath) { | ||
throw new Error('No distPath provided! Provide an absolute path to the UI dist directory.'); | ||
} | ||
fecLogger(LogType.info, 'Starting chrome server...'); | ||
execBin = checkContainerRuntime(); | ||
let tag: string; | ||
if (isProd) { | ||
tag = await getProdRelease(); | ||
} else { | ||
tag = await getLatestCommits(); | ||
} | ||
pullImage(tag); | ||
startServer(tag, serverPort).catch((error) => { | ||
onError(error); | ||
process.exit(1); | ||
}); | ||
await waitOn({ | ||
resources: [`http://${host}:${serverPort}`], | ||
}); | ||
copyIndex(distPath, isPreview); | ||
} | ||
|
||
export default serveChrome; |
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
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
Oops, something went wrong.