feat: adding docker meta label for required blockchain image (#88)

This commit is contained in:
Adam Uhlíř 2022-05-05 13:13:13 +02:00 committed by GitHub
parent 365f77c1ab
commit 51f37f402f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 74 additions and 39 deletions

View File

@ -32,10 +32,10 @@ $ npm install -g @ethersphere/bee-factory
```shell
# This spin up the cluster and exits
$ bee-factory start --detach 1.2.0 1.5.1
$ bee-factory start --detach 1.5.1
# This attaches to the Queen container and displays its logs
$ bee-factory logs queen
$ bee-factory logs queen --follow
# This stops the cluster and keeping the containers so next time they are spinned up the data are kept
# but data are not persisted across version's bump!
@ -43,7 +43,7 @@ $ bee-factory stop
# You can also spin up the cluster without the --detach which then directly
# attaches to the Queen logs and the cluster is terminated upon SIGINT (Ctrl+C)
$ bee-factory start 1.2.0 1.5.1
$ bee-factory start 1.5.1
```
For more details see the `--help` page of the CLI and its commands.

View File

@ -10,9 +10,11 @@ DOCKERFILE
}
dockerbuild() {
BLOCKCHAIN_VERSION=$("$MY_PATH/utils/env-variable-value.sh" BLOCKCHAIN_VERSION)
IMAGE_NAME=$(basename "$1")
IMAGE_NAME="$4/$IMAGE_NAME"
docker build "$1" --no-cache -f "$2" -t "$IMAGE_NAME:$3"
docker build "$1" --no-cache -f "$2" -t "$IMAGE_NAME:$3" --label "org.ethswarm.beefactory.blockchain-version=$BLOCKCHAIN_VERSION"
}
MY_PATH=$(dirname "$0")

View File

@ -296,7 +296,7 @@ done
echo "Check whether the queen node has been connected to every worker..."
ELAPSED_TIME=0
WAITING_TIME=2
TIMEOUT=$((2*30*WAITING_TIME))
TIMEOUT=$((6*30*WAITING_TIME))
RESTRICTED_TOKEN=""
while (( TIMEOUT > ELAPSED_TIME )) ; do
check_queen_is_running

View File

@ -5,13 +5,8 @@ MY_PATH=$( cd "$MY_PATH" && pwd )
BEE_ENV_PREFIX=$("$MY_PATH/utils/env-variable-value.sh" BEE_ENV_PREFIX)
BEE_IMAGE_PREFIX=$("$MY_PATH/utils/env-variable-value.sh" BEE_IMAGE_PREFIX)
BLOCKCHAIN_VERSION=$("$MY_PATH/utils/env-variable-value.sh" BLOCKCHAIN_VERSION)
STATE_COMMIT=$("$MY_PATH/utils/env-variable-value.sh" STATE_COMMIT)
if [ "$STATE_COMMIT" == 'true' ] ; then
BEE_VERSION=$("$MY_PATH/utils/build-image-tag.sh" get)
BLOCKCHAIN_VERSION+="-for-$BEE_VERSION"
echo "Blockchain will have image version: $BLOCKCHAIN_VERSION"
fi
echo "Blockchain will have image version: $BLOCKCHAIN_VERSION"
NAME="$BEE_ENV_PREFIX-blockchain"

View File

@ -51,6 +51,8 @@ GEN_TRAFFIC_UPLOAD_NODE_DEBUG="http://localhost:11635"
CHEQUES_COUNT=1
# Bee version here means the base bee version on which the images will be built
BEE_VERSION=$("$MY_PATH/utils/env-variable-value.sh" BEE_VERSION)
BLOCKCHAIN_VERSION=$("$MY_PATH/utils/env-variable-value.sh" BLOCKCHAIN_VERSION)
SUPPORTED_WORKER_N=4
# handle passed options
@ -123,6 +125,8 @@ if $GEN_TRAFFIC ; then
"$MY_PATH/bee.sh" stop
docker container prune -f
export BLOCKCHAIN_VERSION+="-for-$BEE_VERSION"
fi
"$MY_PATH/bee-docker-build.sh"
"$MY_PATH/blockchain-docker-build.sh"

View File

@ -72,9 +72,6 @@ export class Start extends RootCommand implements LeafCommand {
})
public envPrefix!: string
@Argument({ key: 'blockchain-version', description: 'Blockchain image version', required: true })
public blockchainVersion!: string
@Argument({ key: 'bee-version', description: 'Bee image version', required: true })
public beeVersion!: string
@ -82,7 +79,7 @@ export class Start extends RootCommand implements LeafCommand {
await super.init()
const dockerOptions = await this.buildDockerOptions()
const docker = new Docker(this.console, this.envPrefix, this.imagePrefix)
const docker = new Docker(this.console, this.envPrefix, this.imagePrefix, this.repo)
const status = await docker.getAllStatus()
if (Object.values(status).every(st => st === 'running')) {
@ -111,7 +108,7 @@ export class Start extends RootCommand implements LeafCommand {
text: 'Spawning network...',
spinner: 'point',
color: 'yellow',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
try {
@ -123,14 +120,17 @@ export class Start extends RootCommand implements LeafCommand {
}
const blockchainSpinner = ora({
text: 'Starting blockchain node...',
text: 'Getting blockchain image version...',
spinner: 'point',
color: 'yellow',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
try {
await docker.startBlockchainNode(this.blockchainVersion, this.beeVersion, dockerOptions)
const blockchainVersion = await docker.getBlockchainVersionFromQueenMetadata(this.beeVersion)
blockchainSpinner.text = 'Starting blockchain node...'
await docker.startBlockchainNode(blockchainVersion, dockerOptions)
blockchainSpinner.text = 'Waiting until blockchain is ready...'
await waitForBlockchain()
blockchainSpinner.succeed('Blockchain node is up and listening')
@ -144,7 +144,7 @@ export class Start extends RootCommand implements LeafCommand {
text: 'Starting queen Bee node...',
spinner: 'point',
color: 'yellow',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
try {
@ -164,7 +164,7 @@ export class Start extends RootCommand implements LeafCommand {
text: 'Starting worker Bee nodes...',
spinner: 'point',
color: 'yellow',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
try {
@ -182,7 +182,7 @@ export class Start extends RootCommand implements LeafCommand {
}
if (!this.detach) {
await docker.logs(ContainerType.QUEEN, process.stdout)
await docker.logs(ContainerType.QUEEN, process.stdout, true)
}
}
@ -191,7 +191,7 @@ export class Start extends RootCommand implements LeafCommand {
text: 'Stopping all containers...',
spinner: 'point',
color: 'red',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
await docker.stopAll(false)
@ -201,7 +201,6 @@ export class Start extends RootCommand implements LeafCommand {
private async buildDockerOptions(): Promise<RunOptions> {
return {
repo: this.repo,
fresh: this.fresh,
}
}

View File

@ -43,7 +43,7 @@ export class Stop extends RootCommand implements LeafCommand {
text: 'Stopping all containers...',
spinner: 'point',
color: 'yellow',
isSilent: this.verbosity !== VerbosityLevel.Quiet,
isSilent: this.verbosity === VerbosityLevel.Quiet,
}).start()
await docker.stopAll(true, this.deleteContainers)

View File

@ -11,12 +11,14 @@ const WORKER_IMAGE_NAME_SUFFIX = '-worker'
const NETWORK_NAME_SUFFIX = '-network'
export const WORKER_COUNT = 4
export const BLOCKCHAIN_VERSION_LABEL_KEY = 'org.ethswarm.beefactory.blockchain-version'
// TODO: This should be possible to override with for example ENV variable in case somebody is rocking custom images
const SWAP_FACTORY_ADDRESS = '0x5b1869D9A4C187F2EAa108f3062412ecf0526b24'
const POSTAGE_STAMP_ADDRESS = '0xCfEB869F69431e42cdB54A4F4f105C19C080A601'
const PRICE_ORACLE_ADDRESS = '0x254dffcd3277C0b1660F6d42EFbB754edaBAbC2B'
export interface RunOptions {
repo: string
fresh: boolean
}
@ -52,6 +54,7 @@ export class Docker {
private runningContainers: Container[]
private envPrefix: string
private imagePrefix: string
private repo?: string
private get networkName() {
return `${this.envPrefix}${NETWORK_NAME_SUFFIX}`
@ -60,21 +63,39 @@ export class Docker {
private get blockchainName() {
return `${this.envPrefix}${BLOCKCHAIN_IMAGE_NAME_SUFFIX}`
}
private blockchainImage(blockchainVersion: string) {
if (!this.repo) throw new TypeError('Repo has to be defined!')
return `${this.repo}/${this.imagePrefix}${BLOCKCHAIN_IMAGE_NAME_SUFFIX}:${blockchainVersion}`
}
private get queenName() {
return `${this.envPrefix}${QUEEN_IMAGE_NAME_SUFFIX}`
}
private queenImage(beeVersion: string) {
if (!this.repo) throw new TypeError('Repo has to be defined!')
return `${this.repo}/${this.imagePrefix}${QUEEN_IMAGE_NAME_SUFFIX}:${beeVersion}`
}
private workerName(index: number) {
return `${this.envPrefix}${WORKER_IMAGE_NAME_SUFFIX}-${index}`
}
constructor(console: Logging, envPrefix: string, imagePrefix: string) {
private workerImage(beeVersion: string, workerNumber: number) {
if (!this.repo) throw new TypeError('Repo has to be defined!')
return `${this.repo}/${this.imagePrefix}${WORKER_IMAGE_NAME_SUFFIX}-${workerNumber}:${beeVersion}`
}
constructor(console: Logging, envPrefix: string, imagePrefix: string, repo?: string) {
this.docker = new Dockerode()
this.console = console
this.runningContainers = []
this.envPrefix = envPrefix
this.imagePrefix = imagePrefix
this.repo = repo
}
public async createNetwork(): Promise<void> {
@ -85,11 +106,11 @@ export class Docker {
}
}
public async startBlockchainNode(blockchainVersion: string, beeVersion: string, options: RunOptions): Promise<void> {
public async startBlockchainNode(blockchainVersion: string, options: RunOptions): Promise<void> {
if (options.fresh) await this.removeContainer(this.blockchainName)
const container = await this.findOrCreateContainer(this.blockchainName, {
Image: `${options.repo}/${this.imagePrefix}${BLOCKCHAIN_IMAGE_NAME_SUFFIX}:${blockchainVersion}-for-${beeVersion}`,
Image: this.blockchainImage(blockchainVersion),
name: this.blockchainName,
ExposedPorts: {
'9545/tcp': {},
@ -117,7 +138,7 @@ export class Docker {
if (options.fresh) await this.removeContainer(this.queenName)
const container = await this.findOrCreateContainer(this.queenName, {
Image: `${options.repo}/${this.imagePrefix}${QUEEN_IMAGE_NAME_SUFFIX}:${beeVersion}`,
Image: this.queenImage(beeVersion),
name: this.queenName,
ExposedPorts: {
'1633/tcp': {},
@ -160,7 +181,7 @@ export class Docker {
if (options.fresh) await this.removeContainer(this.workerName(workerNumber))
const container = await this.findOrCreateContainer(this.workerName(workerNumber), {
Image: `${options.repo}/${this.imagePrefix}${WORKER_IMAGE_NAME_SUFFIX}-${workerNumber}:${beeVersion}`,
Image: this.workerImage(beeVersion, workerNumber),
name: this.workerName(workerNumber),
ExposedPorts: {
'1633/tcp': {},
@ -243,6 +264,22 @@ export class Docker {
}
}
public async getBlockchainVersionFromQueenMetadata(beeVersion: string): Promise<string> {
// Lets pull the Queen's image if it is not present
const pullStream = await this.docker.pull(this.queenImage(beeVersion))
await new Promise(res => this.docker.modem.followProgress(pullStream, res))
const queenMetadata = await this.docker.getImage(this.queenImage(beeVersion)).inspect()
const version = queenMetadata.Config.Labels[BLOCKCHAIN_VERSION_LABEL_KEY]
if (!version) {
throw new Error('Blockchain image version was not found in Queen image labels!')
}
return version
}
public async getAllStatus(): Promise<AllStatus> {
return {
queen: await this.getStatusForContainer(ContainerType.QUEEN),

View File

@ -8,7 +8,6 @@ import { Bee, BeeDebug, Reference } from '@ethersphere/bee-js'
import { DockerError } from '../../src/utils/docker'
import { findContainer, waitForUsablePostageStamp } from '../utils/docker'
const BLOCKCHAIN_VERSION = '1.2.0'
const BEE_VERSION = '1.5.1'
let testFailed = false
@ -54,7 +53,7 @@ describe('start command', () => {
'should start cluster',
wrapper(async () => {
// As spinning the cluster with --detach the command will exit once the cluster is up and running
await run(['start', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--detach', BEE_VERSION])
await expect(findContainer(docker, 'queen')).resolves.toBeDefined()
await expect(findContainer(docker, 'blockchain')).resolves.toBeDefined()
@ -84,7 +83,7 @@ describe('start command', () => {
it(
'',
wrapper(async () => {
await run(['start', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--detach', BEE_VERSION])
expect(docker.getNetwork(`${envPrefix}-network`)).toBeDefined()
}),
@ -96,7 +95,7 @@ describe('start command', () => {
beforeAll(async () => {
console.log('(before) Starting up Bee Factory')
await run(['start', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--detach', BEE_VERSION])
console.log('(before) Creating postage stamp ')
const postage = await beeDebug.createPostageBatch('10', 18)
@ -117,7 +116,7 @@ describe('start command', () => {
'',
wrapper(async () => {
console.log('(test) Starting the Bee Factory')
await run(['start', '--fresh', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--fresh', '--detach', BEE_VERSION])
console.log('(test) Trying to fetch the data')
await expect(bee.downloadData(reference)).rejects.toHaveProperty('status', 404)

View File

@ -6,7 +6,6 @@ import { run } from '../utils/run'
import { ENV_ENV_PREFIX_KEY } from '../../src/command/start'
import { findContainer } from '../utils/docker'
const BLOCKCHAIN_VERSION = '1.2.0'
const BEE_VERSION = '1.5.1'
describe('stop command', () => {
@ -27,7 +26,7 @@ describe('stop command', () => {
describe('should stop cluster', () => {
beforeAll(async () => {
// As spinning the cluster with --detach the command will exit once the cluster is up and running
await run(['start', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--detach', BEE_VERSION])
})
it('', async () => {
@ -52,7 +51,7 @@ describe('stop command', () => {
describe('should stop cluster and remove containers', () => {
beforeAll(async () => {
// As spinning the cluster with --detach the command will exit once the cluster is up and running
await run(['start', '--detach', BLOCKCHAIN_VERSION, BEE_VERSION])
await run(['start', '--detach', BEE_VERSION])
})
it('', async () => {