diff --git a/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx b/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx index 21a1b8809..b21315e7c 100644 --- a/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx +++ b/desktop/flipper-server-core/src/devices/ios/iOSContainerUtility.tsx @@ -206,7 +206,7 @@ async function push( return wrapWithErrorMessage( reportPlatformFailures( safeExec( - `${idbPath} --log ${idbLogLevel} file push --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`, + `${idbPath} file push --log ${idbLogLevel} --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`, ) .then(() => { return; @@ -228,7 +228,7 @@ async function pull( return wrapWithErrorMessage( reportPlatformFailures( safeExec( - `${idbPath} --log ${idbLogLevel} file pull --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`, + `${idbPath} file pull --log ${idbLogLevel} --udid ${udid} --bundle-id ${bundleId} '${src}' '${dst}'`, ) .then(() => { return; diff --git a/desktop/flipper-server-core/src/utils/CertificateProvider.tsx b/desktop/flipper-server-core/src/utils/CertificateProvider.tsx index 8ed5cf20f..329204bbe 100644 --- a/desktop/flipper-server-core/src/utils/CertificateProvider.tsx +++ b/desktop/flipper-server-core/src/utils/CertificateProvider.tsx @@ -360,6 +360,7 @@ export default class CertificateProvider { const dir = await tmpDir({unsafeCleanup: true}); const filePath = path.resolve(dir, filename); await fs.writeFile(filePath, contents); + await iosUtil.push( udid, filePath, @@ -494,13 +495,54 @@ export default class CertificateProvider { path.resolve(directory, csrFileName), ); const dir = await tmpDir({unsafeCleanup: true}); - await iosUtil.pull( - deviceId, - originalFile, - bundleId, - dir, - this.config.idbPath, - ); + + // Workaround for idb weirdness + // Originally started at D27590885 + // Re-appared at https://github.com/facebook/flipper/issues/3009 + // + // People reported various workarounds. None of them worked consistently for everyone. + // Usually, the workarounds included re-building idb from source or re-installing it. + // + // The only more or less reasonable explanation I was able to find is that the final behavior depends on whether the idb_companion is local or not. + // + // This is how idb_companion sets its locality + // https://github.com/facebook/idb/blob/main/idb_companion/Server/FBIDBServiceHandler.mm#L1507 + // idb sends a connection request and provides a file path to a temporary file. idb_companion checks if it can access that file. + // + // So when it is "local", the pulled filed is written directly to the destination path + // https://github.com/facebook/idb/blob/main/idb/grpc/client.py#L698 + // So it is expected that the destination path ends with a file to write to. + // However, if the companion is remote, then we seem to get here https://github.com/facebook/idb/blob/71791652efa2d5e6f692cb8985ff0d26b69bf08f/idb/common/tar.py#L232 + // Where we create a tree of directories and write the file stream there. + // + // So the only explanation I could come up with is that somehow, by re-installing idb and playing with the env, people could affect the locality of the idb_companion. + // + // The ultimate workaround is to try pulling the cert file without the cert name attached first, if it fails, try to append it. + try { + await iosUtil.pull( + deviceId, + originalFile, + bundleId, + dir, + this.config.idbPath, + ); + } catch (e) { + console.warn( + 'Original idb pull failed. Most likely it is a physical device that requires us to handle the dest path dirrently. Forcing a re-try with the updated dest path. See D32106952 for details. Original error:', + e, + ); + await iosUtil.pull( + deviceId, + originalFile, + bundleId, + path.join(dir, csrFileName), + this.config.idbPath, + ); + console.info( + 'Subsequent idb pull succeeded. Nevermind previous wranings.', + ); + } + const items = await fs.readdir(dir); if (items.length > 1) { throw new Error('Conflict in temp dir');