Skip to content

Commit 0ad9360

Browse files
authored
fix(codecatalyst): Failed to write SSH config #3395
* Fix regression with ssh config, from 6cfe24a * Guard against inaccurate error messages
1 parent d1ead62 commit 0ad9360

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

src/codecatalyst/tools.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ async function verifySSHHost({
254254
const sshConfigPath = getSshConfigPath()
255255
try {
256256
await fs.ensureDir(path.dirname(path.dirname(sshConfigPath)), { mode: 0o755 })
257-
await fs.mkdir(path.dirname(sshConfigPath), 0o700)
257+
await fs.ensureDir(path.dirname(sshConfigPath), 0o700)
258258
await fs.appendFile(sshConfigPath, section, { mode: 0o600 })
259259
} catch (e) {
260260
const message = localize(

src/shared/errors.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -464,7 +464,8 @@ export class PermissionsError extends ToolkitError {
464464
public readonly uri: vscode.Uri,
465465
public readonly stats: fs.Stats,
466466
public readonly userInfo: os.UserInfo<string>,
467-
public readonly expected: PermissionsTriplet
467+
public readonly expected: PermissionsTriplet,
468+
source?: unknown
468469
) {
469470
const mode = `${stats.isDirectory() ? 'd' : '-'}${modeToString(stats.mode)}`
470471
const owner = stats.uid === userInfo.uid ? userInfo.username : stats.uid
@@ -475,6 +476,13 @@ export class PermissionsError extends ToolkitError {
475476
.join('')
476477
const actualText = !isAmbiguous ? actual : `${mode.slice(-6, -3)} & ${mode.slice(-3)} (ambiguous)`
477478

479+
// Guard against surfacing confusing error messages. If the actual perms equal the resolved
480+
// perms then odds are it wasn't really a permissions error. Some operating systems report EPERM
481+
// in situations that aren't related to permissions at all.
482+
if (actual === resolvedExpected && !isAmbiguous && source !== undefined) {
483+
throw source
484+
}
485+
478486
super(`${uri.fsPath} has incorrect permissions. Expected ${resolvedExpected}, found ${actualText}.`, {
479487
code: 'InvalidPermissions',
480488
details: {

src/shared/systemUtilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function createPermissionsErrorHandler(
3636
throw await createPermissionsErrorHandler(vscode.Uri.joinPath(uri, '..'), '*wx')(err2, depth + 1)
3737
})
3838

39-
throw new PermissionsError(uri, stats, userInfo, perms)
39+
throw new PermissionsError(uri, stats, userInfo, perms, err)
4040
}
4141
}
4242

@@ -126,7 +126,7 @@ export class SystemUtilities {
126126
})
127127
if ((stats.mode & fs.constants.S_IXUSR) === 0) {
128128
const userInfo = os.userInfo({ encoding: 'utf-8' })
129-
throw new PermissionsError(dirUri, stats, userInfo, '*wx')
129+
throw new PermissionsError(dirUri, stats, userInfo, '*wx', err)
130130
}
131131
}
132132

src/test/codecatalyst/tools.test.ts

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*/
55

66
import * as vscode from 'vscode'
7+
import * as sinon from 'sinon'
78
import * as path from 'path'
89
import * as http from 'http'
910
import * as assert from 'assert'
@@ -18,8 +19,9 @@ import {
1819
getCodeCatalystSsmEnv,
1920
sshLogFileLocation,
2021
} from '../../codecatalyst/model'
21-
import { readFile, writeFile } from 'fs-extra'
22+
import { mkdir, readFile, writeFile } from 'fs-extra'
2223
import { StartDevEnvironmentSessionRequest } from 'aws-sdk/clients/codecatalyst'
24+
import { SystemUtilities } from '../../shared/systemUtilities'
2325

2426
describe('SSH Agent', function () {
2527
it('can start the agent on windows', async function () {
@@ -130,4 +132,27 @@ describe('Connect Script', function () {
130132
assert.fail(`Connect script should exit with a zero status:\n${message}`)
131133
}
132134
})
135+
136+
describe('~/.ssh', function () {
137+
let tmpDir: string
138+
139+
beforeEach(async function () {
140+
tmpDir = await makeTemporaryToolkitFolder()
141+
sinon.stub(SystemUtilities, 'getHomeDirectory').returns(tmpDir)
142+
})
143+
144+
afterEach(async function () {
145+
sinon.restore()
146+
await SystemUtilities.delete(tmpDir, { recursive: true })
147+
})
148+
149+
it('works if the .ssh directory is missing', async function () {
150+
;(await ensureConnectScript(context)).unwrap()
151+
})
152+
153+
it('works if the .ssh directory exists but has different perms', async function () {
154+
await mkdir(path.join(tmpDir, '.ssh'), 0o777)
155+
;(await ensureConnectScript(context)).unwrap()
156+
})
157+
})
133158
})

0 commit comments

Comments
 (0)