mirror of
https://github.com/balena-io/balena-cli.git
synced 2024-12-18 21:27:51 +00:00
wip
This commit is contained in:
parent
9e4dd3fce2
commit
eed4a385a9
@ -882,6 +882,7 @@ Examples:
|
||||
|
||||
$ balena build --fleet myFleet
|
||||
$ balena build ./source/ --fleet myorg/myfleet
|
||||
$ balena build ./source/ --fleet myorg/myfleet --docker-compose my-custom-compose.yml
|
||||
$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated
|
||||
$ balena build --docker /var/run/docker.sock --fleet myFleet # Linux, Mac
|
||||
$ balena build --docker //./pipe/docker_engine --fleet myFleet # Windows
|
||||
@ -915,6 +916,10 @@ Use QEMU for ARM architecture emulation during the image build
|
||||
|
||||
Alternative Dockerfile name/path, relative to the source folder
|
||||
|
||||
#### --docker-compose DOCKER-COMPOSE
|
||||
|
||||
Alternative compose yml file, relative to the source folder
|
||||
|
||||
#### --nologs
|
||||
|
||||
Hide the image build log output (produce less verbose output)
|
||||
@ -1087,6 +1092,7 @@ Examples:
|
||||
|
||||
$ balena deploy myFleet
|
||||
$ balena deploy myorg/myfleet --build --source myBuildDir/
|
||||
$ balena deploy myorg/myfleet --builld --source myBuildDir/ --docker-compose my-custom-compose.yml
|
||||
$ balena deploy myorg/myfleet --build --source myBuildDir/ --note "this is the note for this release"
|
||||
$ balena deploy myorg/myfleet myRepo/myImage
|
||||
$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"
|
||||
@ -1140,6 +1146,10 @@ Use QEMU for ARM architecture emulation during the image build
|
||||
|
||||
Alternative Dockerfile name/path, relative to the source folder
|
||||
|
||||
#### --docker-compose DOCKER-COMPOSE
|
||||
|
||||
Alternative compose yml file, relative to the source folder
|
||||
|
||||
#### --nologs
|
||||
|
||||
Hide the image build log output (produce less verbose output)
|
||||
@ -3281,6 +3291,7 @@ Examples:
|
||||
$ balena push myFleet -s <source directory>
|
||||
$ balena push myFleet --source <source directory> --note "this is the note for this release"
|
||||
$ balena push myFleet --release-tag key1 "" key2 "value2 with spaces"
|
||||
$ balena push myorg/myfleet --docker-compose my-custom-compose.yml
|
||||
$ balena push myorg/myfleet
|
||||
|
||||
$ balena push 10.0.0.1
|
||||
@ -3315,6 +3326,10 @@ suspected issues with the balenaCloud backend.
|
||||
|
||||
Alternative Dockerfile name/path, relative to the source folder
|
||||
|
||||
#### --docker-compose DOCKER-COMPOSE
|
||||
|
||||
Alternative compose yml file, relative to the source folder
|
||||
|
||||
#### -c, --nocache
|
||||
|
||||
Don't use cached layers of previously built images for this project. This
|
||||
|
@ -67,6 +67,7 @@ ${dockerignoreHelp}
|
||||
public static examples = [
|
||||
'$ balena build --fleet myFleet',
|
||||
'$ balena build ./source/ --fleet myorg/myfleet',
|
||||
'$ balena build ./source/ --fleet myorg/myfleet --docker-compose my-custom-compose.yml',
|
||||
'$ balena build --deviceType raspberrypi3 --arch armv7hf --emulated',
|
||||
'$ balena build --docker /var/run/docker.sock --fleet myFleet # Linux, Mac',
|
||||
'$ balena build --docker //./pipe/docker_engine --fleet myFleet # Windows',
|
||||
|
@ -98,6 +98,7 @@ ${dockerignoreHelp}
|
||||
public static examples = [
|
||||
'$ balena deploy myFleet',
|
||||
'$ balena deploy myorg/myfleet --build --source myBuildDir/',
|
||||
'$ balena deploy myorg/myfleet --builld --source myBuildDir/ --docker-compose my-custom-compose.yml',
|
||||
'$ balena deploy myorg/myfleet --build --source myBuildDir/ --note "this is the note for this release"',
|
||||
'$ balena deploy myorg/myfleet myRepo/myImage',
|
||||
'$ balena deploy myFleet myRepo/myImage --release-tag key1 "" key2 "value2 with spaces"',
|
||||
|
@ -78,6 +78,7 @@ export default class PushCmd extends Command {
|
||||
'$ balena push myFleet -s <source directory>',
|
||||
'$ balena push myFleet --source <source directory> --note "this is the note for this release"',
|
||||
'$ balena push myFleet --release-tag key1 "" key2 "value2 with spaces"',
|
||||
'$ balena push myorg/myfleet --docker-compose my-custom-compose.yml',
|
||||
'$ balena push myorg/myfleet',
|
||||
'',
|
||||
'$ balena push 10.0.0.1',
|
||||
@ -121,6 +122,10 @@ export default class PushCmd extends Command {
|
||||
description:
|
||||
'Alternative Dockerfile name/path, relative to the source folder',
|
||||
}),
|
||||
'docker-compose': Flags.string({
|
||||
description:
|
||||
'Alternative compose yml file, relative to the source folder',
|
||||
}),
|
||||
nocache: Flags.boolean({
|
||||
description: stripIndent`
|
||||
Don't use cached layers of previously built images for this project. This
|
||||
@ -365,6 +370,7 @@ export default class PushCmd extends Command {
|
||||
dockerfilePath,
|
||||
registrySecrets,
|
||||
multiDockerignore: options['multi-dockerignore'],
|
||||
composefileName: options['docker-compose'],
|
||||
nocache: options.nocache,
|
||||
pull: options.pull,
|
||||
noParentCheck: options['noparent-check'],
|
||||
|
@ -47,6 +47,12 @@ export class NoPortsDefinedError extends ExpectedError {
|
||||
|
||||
export class SIGINTError extends ExpectedError {}
|
||||
|
||||
export class CompositionFileNotFoundError extends ExpectedError {
|
||||
constructor(filePath: string) {
|
||||
super(`Composition file not found at: "${filePath}"`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* instanceOf is a more reliable implementation of the plain `instanceof`
|
||||
* typescript operator, for use with TypedError errors when the error
|
||||
|
2
lib/utils/compose-types.d.ts
vendored
2
lib/utils/compose-types.d.ts
vendored
@ -53,6 +53,7 @@ export interface TaggedImage {
|
||||
export interface ComposeOpts {
|
||||
convertEol: boolean;
|
||||
dockerfilePath?: string;
|
||||
composefileName?: string;
|
||||
inlineLogs?: boolean;
|
||||
multiDockerignore: boolean;
|
||||
noParentCheck: boolean;
|
||||
@ -65,6 +66,7 @@ export interface ComposeCliFlags {
|
||||
emulated: boolean;
|
||||
dockerfile?: string;
|
||||
nologs: boolean;
|
||||
'docker-compose'?: string;
|
||||
'multi-dockerignore': boolean;
|
||||
'noparent-check': boolean;
|
||||
'registry-secrets'?: RegistrySecrets;
|
||||
|
@ -40,6 +40,7 @@ export function generateOpts(options: {
|
||||
dockerfile?: string;
|
||||
'multi-dockerignore': boolean;
|
||||
'noparent-check': boolean;
|
||||
'docker-compose'?: string;
|
||||
}): Promise<ComposeOpts> {
|
||||
const { promises: fs } = require('fs') as typeof import('fs');
|
||||
return fs.realpath(options.source || '.').then((projectPath) => ({
|
||||
@ -49,6 +50,7 @@ export function generateOpts(options: {
|
||||
convertEol: !options['noconvert-eol'],
|
||||
dockerfilePath: options.dockerfile,
|
||||
multiDockerignore: !!options['multi-dockerignore'],
|
||||
composefileName: options['docker-compose'],
|
||||
noParentCheck: options['noparent-check'],
|
||||
}));
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ import type * as MultiBuild from '@balena/compose/dist/multibuild';
|
||||
import * as semver from 'semver';
|
||||
import type { Duplex, Readable } from 'stream';
|
||||
import type { Pack } from 'tar-stream';
|
||||
import { ExpectedError } from '../errors';
|
||||
import { CompositionFileNotFoundError, ExpectedError } from '../errors';
|
||||
import {
|
||||
BuiltImage,
|
||||
ComposeOpts,
|
||||
@ -128,7 +128,11 @@ export async function loadProject(
|
||||
composeStr = compose.defaultComposition(image);
|
||||
} else {
|
||||
logger.logDebug('Resolving project...');
|
||||
[composeName, composeStr] = await resolveProject(logger, opts.projectPath);
|
||||
[composeName, composeStr] = await resolveProject({
|
||||
logger,
|
||||
projectRoot: opts.projectPath,
|
||||
compositionFile: opts.composefileName,
|
||||
});
|
||||
|
||||
if (composeName) {
|
||||
if (opts.dockerfilePath) {
|
||||
@ -198,33 +202,55 @@ async function mergeDevComposeOverlay(
|
||||
return composeStr;
|
||||
}
|
||||
|
||||
async function getDefaultCompositionFileName(
|
||||
projectRoot: string,
|
||||
): Promise<string | undefined> {
|
||||
for (const fname of compositionFileNames) {
|
||||
if (await exists(path.join(projectRoot, fname))) {
|
||||
return fname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface ResolveProjectParameters {
|
||||
logger: Logger;
|
||||
projectRoot: string;
|
||||
quiet?: boolean;
|
||||
compositionFile?: string;
|
||||
}
|
||||
/**
|
||||
* Look into the given directory for valid compose files and return
|
||||
* the contents of the first one found.
|
||||
*/
|
||||
async function resolveProject(
|
||||
logger: Logger,
|
||||
projectRoot: string,
|
||||
async function resolveProject({
|
||||
logger,
|
||||
projectRoot,
|
||||
quiet = false,
|
||||
): Promise<[string, string]> {
|
||||
let composeFileName = '';
|
||||
compositionFile,
|
||||
}: ResolveProjectParameters): Promise<[string, string]> {
|
||||
logger.logError(`Iam on resolve project and have ${compositionFile}`);
|
||||
const composeFileName =
|
||||
compositionFile ?? (await getDefaultCompositionFileName(projectRoot));
|
||||
let composeFileContents = '';
|
||||
for (const fname of compositionFileNames) {
|
||||
const fpath = path.join(projectRoot, fname);
|
||||
if (await exists(fpath)) {
|
||||
logger.logDebug(`${fname} file found at "${projectRoot}"`);
|
||||
composeFileName = fname;
|
||||
try {
|
||||
composeFileContents = await fs.readFile(fpath, 'utf8');
|
||||
} catch (err) {
|
||||
logger.logError(`Error reading composition file "${fpath}":\n${err}`);
|
||||
throw err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (composeFileName == null) {
|
||||
throw new CompositionFileNotFoundError(projectRoot);
|
||||
}
|
||||
|
||||
const fpath = path.join(projectRoot, composeFileName);
|
||||
if (!(await exists(fpath))) {
|
||||
throw new CompositionFileNotFoundError(fpath);
|
||||
}
|
||||
|
||||
logger.logDebug(`Using composition file at "${fpath}"`);
|
||||
try {
|
||||
composeFileContents = await fs.readFile(fpath, 'utf8');
|
||||
} catch (err) {
|
||||
logger.logError(`Error reading composition file "${fpath}":\n${err}`);
|
||||
throw err;
|
||||
}
|
||||
if (!quiet && !composeFileName) {
|
||||
logger.logInfo(`No "docker-compose.yml" file found at "${projectRoot}"`);
|
||||
logger.logInfo(`No composition file found at "${projectRoot}"`);
|
||||
}
|
||||
|
||||
return [composeFileName, composeFileContents];
|
||||
@ -680,15 +706,17 @@ async function loadBuildMetatada(
|
||||
export async function getServiceDirsFromComposition(
|
||||
sourceDir: string,
|
||||
composition?: Composition,
|
||||
compositionFile?: string,
|
||||
): Promise<Dictionary<string>> {
|
||||
const { createProject } = await import('./compose');
|
||||
const serviceDirs: Dictionary<string> = {};
|
||||
if (!composition) {
|
||||
const [, composeStr] = await resolveProject(
|
||||
Logger.getLogger(),
|
||||
sourceDir,
|
||||
true,
|
||||
);
|
||||
const [, composeStr] = await resolveProject({
|
||||
logger: Logger.getLogger(),
|
||||
projectRoot: sourceDir,
|
||||
quiet: true,
|
||||
compositionFile,
|
||||
});
|
||||
if (composeStr) {
|
||||
composition = createProject(sourceDir, composeStr).composition;
|
||||
}
|
||||
@ -1652,6 +1680,9 @@ export const composeCliFlags = {
|
||||
description:
|
||||
'Alternative Dockerfile name/path, relative to the source folder',
|
||||
}),
|
||||
'docker-compose': Flags.string({
|
||||
description: 'Alternative compose yml file, relative to the source folder',
|
||||
}),
|
||||
nologs: Flags.boolean({
|
||||
description:
|
||||
'Hide the image build log output (produce less verbose output)',
|
||||
|
@ -56,6 +56,7 @@ export interface DeviceDeployOptions {
|
||||
deviceHost: string;
|
||||
devicePort?: number;
|
||||
dockerfilePath?: string;
|
||||
composefileName?: string;
|
||||
registrySecrets: RegistrySecrets;
|
||||
multiDockerignore: boolean;
|
||||
nocache: boolean;
|
||||
@ -182,6 +183,7 @@ export async function deployToDevice(opts: DeviceDeployOptions): Promise<void> {
|
||||
const project = await loadProject(globalLogger, {
|
||||
convertEol: opts.convertEol,
|
||||
dockerfilePath: opts.dockerfilePath,
|
||||
composefileName: opts.composefileName,
|
||||
multiDockerignore: opts.multiDockerignore,
|
||||
noParentCheck: opts.noParentCheck,
|
||||
projectName: 'local',
|
||||
|
Loading…
Reference in New Issue
Block a user