Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix mac address resolution on touchbar devices #77033

Merged
merged 7 commits into from
Jul 15, 2019
Merged

Conversation

sbatten
Copy link
Member

@sbatten sbatten commented Jul 10, 2019

  • Fixes an issue with mac addresses on MBP with TouchBar.
  • Removes unnecessary dependencies shipped to get mac address of machine
  • Sends an event to help understand machines with this issue

@sbatten sbatten self-assigned this Jul 10, 2019
@sbatten sbatten requested review from bpasero and kieferrm July 10, 2019 00:55
Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbatten lots of changes are needed, I am not sure if you maybe asked for a review too early before finishing this PR? There is a "Draft" feature for PRs to handle those cases for the future.

Besides my feedback, you also seem to miss test coverage from id.test.ts where we still seem to test the old getmac solution and not your new solution.

Are we at risk of changing our machine ID resolution to a new system that is potentially unsafe? Or was the getmac module doing the same thing?

//cc @kieferrm given the potential impact of this change on our telemetry

resolve(undefined);
}
}, err => {
function getMacMachineId(): Promise<string | undefined> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This really is hard to read, I suggest to rewrite the 2 methods using async:

let machineId: Promise<string>;
export async function getMachineId(): Promise<string> {
	if (!machineId) {
		machineId = (async () => {
			const id = await getMacAddress();

			return id || uuid.generateUuid(); // fallback, generate a UUID
		})();
	}

	return machineId;
}

async function getMacAddress(): Promise<string | undefined> {
	try {
		const crypto = await import('crypto');
		const macAddress = await getMac();

		return crypto.createHash('sha256').update(macAddress, 'utf8').digest('hex');
	} catch (error) {
		errors.onUnexpectedError(error);
		return undefined;
	}
}

}, err => {
function getMacMachineId(): Promise<string | undefined> {
return import('crypto').then(crypto => {
return getMac().then((macAddress: string) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer seem to depend on getmac. Why does this PR not include the necessary changes to remove getmac from our package.json, yarn.lock, getmac.d.ts, etc.?

export function getMac(): Promise<string> {
return new Promise((resolve, reject) => {
try {
exec(isWindows ? cmdline.windows : cmdline.unix, { timeout: 10000 }, (err, stdout, stdin) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure we can trust the timeout parameter. It makes sense to me to have it, but I would also have the timeout mechanism we used to have before where we would resolve the promise after 10s automatically instead of relying on the OS to do this.

@@ -363,6 +364,12 @@ export class CodeApplication extends Disposable {
const machineId = await this.resolveMachineId();
this.logService.trace(`Resolved machine identifier: ${machineId}`);

let trueMachineId;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am super confused now by this code which seems to resolve the machine ID twice depending on some value of the machine ID. I suggest to do this all from within ONE method and not two that does the right thing depending on the state. E.g. resolveMachineId should return the "true" machine ID in case needed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bpasero we need to resolve 2 separate machined ids, not just one. We should always return and use the originally calculated machine id as machineId. TrueMachineId is intended only as a disambiguation in this specific case.

@bpasero
Copy link
Member

bpasero commented Jul 10, 2019

Oh, only now saw that @kieferrm is also on the review list 👍

@sbatten
Copy link
Member Author

sbatten commented Jul 10, 2019

@bpasero, the intent of this change is to maintain the existing calculation. we should not see a change in mac address resolution.

@bpasero bpasero self-requested a review July 11, 2019 07:39
Copy link
Member

@bpasero bpasero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sbatten I pushed some changes:

  • the timeout was never cleared (f4ad2d0)
  • the resolution of machine ID is now in one method (c5cbffd)

I still think we can improve this: there is now a machineId and a trueMachineId floating around in app.ts. I find that very hard to understand by just reading the code. I suggest to introduce an interface IMachineId { original: string, resolved: string } that we pass around. As you can see, machineId is being used in many places (also shared process) but the new trueMachineId is only used in one place it seems. How can I know which ID to use in which case?

An alternative and even better solution would be: replace the machineId with the newly resolved machineId if it matches 6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead. I see no big value in using the machine ID 6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead for telemetry if so many mac users might have it?

E.g. it then becomes:

private async resolveMachineId(): Promise<string> {

	// We cache the machineId for faster lookups on startup
	// and resolve it only once initially if not cached
	let machineId = this.stateService.getItem<string>(CodeApplication.MACHINE_ID_KEY);
	if (isMacintosh && machineId === '6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead') {
		machineId = undefined;
	}

	if (!machineId) {
		machineId = await getMachineId();

		this.stateService.setItem(CodeApplication.MACHINE_ID_KEY, machineId);
	}

	return machineId;
}

(probably would need to store some state flag to prevent always resolving the machine ID if it always resolves to 6c9d2bc8f91b89624add29c0abeae7fb42bf539fa1cdb2e3e57cd668fa9bcead)

@sbatten
Copy link
Member Author

sbatten commented Jul 11, 2019

@kieferrm discussed with ben offline so this is ready to merge, PTAL

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants