Skip to content

Commit

Permalink
Fix: devtool-update-recipe command in containers
Browse files Browse the repository at this point in the history
When using the devtool-update-recipe command in a container, the
paths have to be resolved between host and container.
  • Loading branch information
deribaucourt committed Dec 21, 2023
1 parent 3b096df commit 2b1c8bc
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 24 deletions.
67 changes: 46 additions & 21 deletions client/src/driver/BitBakeProjectScanner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ export class BitBakeProjectScanner {
if (containerDirInode === hostDirInode) {
this.containerMountPoint = containerDir
this.hostMountPoint = hostDir
logger.info(`Found container mount point: ${this.containerMountPoint} -> ${this.hostMountPoint}`)
return
}
containerDir = path.dirname(containerDir)
Expand Down Expand Up @@ -214,37 +215,61 @@ export class BitBakeProjectScanner {
}
}

/// If a docker container is used, the workdir may be different from the host system.
/// This function resolves the path to the host system.
async resolveContainerPath (layerPath: string | undefined): Promise<string | undefined> {
if (layerPath === undefined) {
private async resolveCorrespondingPath (inputPath: string | undefined, hostToContainer: boolean): Promise<string | undefined> {
if (inputPath === undefined) {
return undefined
}
const hostWorkdir = this.bitbakeDriver?.bitbakeSettings.workingDirectory
if (hostWorkdir === undefined) {
throw new Error('hostWorkdir is undefined')
}
if (this.containerMountPoint === undefined) {
await this.scanContainerMountPoint(layerPath, hostWorkdir)
if (this.containerMountPoint === undefined && !hostToContainer) {
// Should only be called through scanAvailableLayers()
const hostWorkdir = this.bitbakeDriver?.bitbakeSettings.workingDirectory
if (hostWorkdir === undefined) {
throw new Error('hostWorkdir is undefined')
}
await this.scanContainerMountPoint(inputPath, hostWorkdir)
}
if (this.containerMountPoint === undefined || this.hostMountPoint === undefined) {
return layerPath
const origMountPoint = hostToContainer ? this.hostMountPoint : this.containerMountPoint
const destMountPoint = hostToContainer ? this.containerMountPoint : this.hostMountPoint
const fileExistsFn = hostToContainer ? this.existsInContainer.bind(this) : fs.existsSync
if (origMountPoint === undefined || destMountPoint === undefined) {
return inputPath
}
const relativePath = path.relative(this.containerMountPoint, layerPath)
let resolvedPath = path.resolve(this.hostMountPoint, relativePath)
if (!fs.existsSync(resolvedPath)) {
const relativePath = path.relative(origMountPoint, inputPath)
let resolvedPath = path.resolve(destMountPoint, relativePath)
if (!await fileExistsFn(resolvedPath)) {
// This makes it work with the default kas-container configuration (/work & /build volumes)
resolvedPath = path.resolve(this.hostMountPoint, relativePath.replace('../', ''))
resolvedPath = path.resolve(destMountPoint, relativePath.replace('../', ''))
}
if (!fs.existsSync(resolvedPath)) {
await vscode.window.showErrorMessage(`It seems you are using containers and the Bitbake extension can't
guess the corresponding mount points for ${layerPath}.\n\nYou should adjust your docker volumes to use the same
uris as those present on your host machine`, { modal: true })
return layerPath
if (!await fileExistsFn(resolvedPath)) {
// Showing a modal here because this can only happend through the command devtool-update-recipe which is not used often
await vscode.window.showErrorMessage(
'Bitbake extension couldn\'t locate a file.', {
modal: true,
detail: `It looks like you are using the bitbake.commandWrapper setting to use a docker container.\n
Couldn't find ${inputPath} corresponding paths inside and outside of the container.\n
You should adjust your docker volumes to use the same URIs as those present on your host machine.`
})
return inputPath
}
return resolvedPath
}

/// If a docker container is used, the workdir may be different from the host system.
/// This function resolves the path to the host system.
async resolveContainerPath (layerPath: string | undefined): Promise<string | undefined> {
return await this.resolveCorrespondingPath(layerPath, false)
}

/// This function mirrors resolveContainerPath, but for the other direction.
async resolveHostPath (containerPath: string | undefined): Promise<string | undefined> {
return await this.resolveCorrespondingPath(containerPath, true)
}

private async existsInContainer (containerPath: string): Promise<boolean> {
const process = runBitbakeTerminalCustomCommand(this._bitbakeDriver, 'test -e ' + containerPath, 'BitBake: Test file', true)
const res = finishProcessExecution(process)
return (await res).status === 0
}

private searchFiles (pattern: string): ElementInfo[] {
const elements: ElementInfo[] = new Array < ElementInfo >()

Expand Down
8 changes: 5 additions & 3 deletions client/src/ui/BitbakeCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import path from 'path'
import { BitbakeRecipeTreeItem } from './BitbakeRecipesView'
import { type BitBakeProjectScanner } from '../driver/BitBakeProjectScanner'
import { extractRecipeName } from '../lib/src/utils/files'
import { runBitbakeTerminal, runBitbakeTerminalCustomCommand } from './BitbakeTerminal'
import { BitbakePseudoTerminal, runBitbakeTerminal, runBitbakeTerminalCustomCommand } from './BitbakeTerminal'

Check failure on line 16 in client/src/ui/BitbakeCommands.ts

View workflow job for this annotation

GitHub Actions / build (20)

'BitbakePseudoTerminal' is defined but never used
import { type BitbakeDriver } from '../driver/BitbakeDriver'
import { sanitizeForShell } from '../lib/src/BitbakeSettings'
import { type BitbakeTaskDefinition, type BitbakeTaskProvider } from './BitbakeTaskProvider'
Expand Down Expand Up @@ -238,12 +238,13 @@ async function devtoolUpdateCommand (bitbakeWorkspace: BitbakeWorkspace, bitBake
const chosenRecipe = await selectRecipe(bitbakeWorkspace, uri)
if (chosenRecipe === undefined) { return }
const chosenLayer = await pickLayer(originalRecipeChoice, bitBakeProjectScanner)
const chosenLayerPath = await bitBakeProjectScanner.resolveHostPath(chosenLayer?.path)
let command = ''

if (chosenLayer?.name === originalRecipeChoice) {
command = `devtool update-recipe ${chosenRecipe}`
} else {
command = `devtool update-recipe ${chosenRecipe} --append ${chosenLayer?.path}`
command = `devtool update-recipe ${chosenRecipe} --append ${chosenLayerPath}`
}

logger.debug(`Command: devtool-update: ${chosenRecipe}`)
Expand All @@ -264,7 +265,8 @@ async function openDevtoolUpdateBBAppend (res: SpawnSyncReturns<Buffer>, bitBake
logger.error('Could not find bbappend file')
return
}
const bbappendPath = match[1]
let bbappendPath = match[1]
bbappendPath = await bitBakeProjectScanner.resolveContainerPath(bbappendPath) as string
const bbappendUri = vscode.Uri.file(bbappendPath)
logger.debug(`Opening devtool-update-recipe bbappend file: ${bbappendPath}`)
await vscode.commands.executeCommand('vscode.open', bbappendUri)
Expand Down

0 comments on commit 2b1c8bc

Please sign in to comment.