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

add cluster icon migration code #673

Merged
merged 8 commits into from
Aug 25, 2020
Merged

Conversation

Nokel81
Copy link
Collaborator

@Nokel81 Nokel81 commented Aug 11, 2020

This PR adds a migration to the cluster store so that icon that were previously stored on the file system are instead stored in their base64 encoding within the cluster store.

@Nokel81 Nokel81 requested a review from ixrock August 11, 2020 15:00
@Nokel81 Nokel81 self-assigned this Aug 11, 2020
@Nokel81 Nokel81 requested a review from jakolehm August 11, 2020 15:00
Copy link
Member

@ixrock ixrock left a comment

Choose a reason for hiding this comment

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

LGTM

src/migrations/cluster-store/3.6.0-beta.1.ts Outdated Show resolved Hide resolved
*/
try {
if (cluster.preferences.icon) {
const fileData = fse.readFileSync(cluster.preferences.icon);
Copy link
Member

Choose a reason for hiding this comment

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

Is it was absolute path to icon, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@Nokel81 Nokel81 requested a review from ixrock August 11, 2020 16:55
@Nokel81
Copy link
Collaborator Author

Nokel81 commented Aug 11, 2020

I don't know the exact problems that using async migration functions might lend themselves to, but it is something that I would like to see changed (I raised sindresorhus/conf#123) to hopefully get the ball rolling.

@nevalla
Copy link
Contributor

nevalla commented Aug 17, 2020

Had some issues while testing this. Need to figure out is it user error or real issue.

@nevalla
Copy link
Contributor

nevalla commented Aug 19, 2020

So, back to my issue. The error I got is the following:

STORE MIGRATION (/Users/lauri/Library/Application Support/LensDev/lens-cluster-store.json): 3.6.0-beta.1
[0] Number of clusters to migrate:  1
[0] Failed to migrate cluster icon for cluster "c959e2c4-45dc-4a1a-93fd-dd0494c520eb" Error: ENOENT: no such file or directory, open 'store:///icons/minikube-minikube-logo.png'
[0]     at Object.openSync (fs.js:440:3)
[0]     at Object.func [as openSync] (electron/js2c/asar.js:140:31)
[0]     at Object.readFileSync (fs.js:342:35)
[0]     at Object.fs.readFileSync (electron/js2c/asar.js:542:40)
[0]     at eval (webpack-internal:///./src/migrations/cluster-store/3.6.0-beta.1.ts:52:86)
[0]     at Array.map (<anonymous>)
[0]     at run (webpack-internal:///./src/migrations/cluster-store/3.6.0-beta.1.ts:33:14)
[0]     at 3.6.0-beta.1 (webpack-internal:///./src/migrations/migration-wrapper.ts:14:13)
[0]     at Conf._migrate (/Users/lauri/Projects/lens/node_modules/conf/dist/source/index.js:400:17)
[0]     at new Conf (/Users/lauri/Projects/lens/node_modules/conf/dist/source/index.js:144:18) {
[0]   errno: -2,
[0]   syscall: 'open',
[0]   code: 'ENOENT',
[0]   path: 'store:///icons/minikube-minikube-logo.png'
[0] }

So the icon stored in cluster store is in format of store://... so we can't read it directly, but we need to convert that to real file path. Also found mime-types npm package that offers the same functionality but without promises. With these changes I tried with this:

...
        /**
        * migrate cluster icon
        */
        try {
          if (cluster.preferences.icon) {
            const fileName = path.join((app || remote.app).getPath("userData"), cluster.preferences.icon.replace("store://", ""))
            const fileData = fse.readFileSync(fileName);
            const mimeType = mime.lookup(fileName)
            
            if (!mimeType) {
              throw "unknown icon file type, deleting...";
            }
           
            cluster.preferences.icon = `data:${mimeType};base64, ${fileData.toString('base64')}`;
...

and that seem to work better.

@nevalla
Copy link
Contributor

nevalla commented Aug 19, 2020

oh, noticed that images seem to be rendered fine without mimetype too, ie data:;base64, ..... But should not hurt to put correct in place.

Copy link
Contributor

@nevalla nevalla left a comment

Choose a reason for hiding this comment

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

Please take a look the comment I've added.

@Nokel81
Copy link
Collaborator Author

Nokel81 commented Aug 19, 2020

@nevalla mime-types is not the same as as file-type. The former merely looks at the file extension while the later use the actual contents of the file.

@nevalla
Copy link
Contributor

nevalla commented Aug 19, 2020

@nevalla mime-types is not the same as as file-type. The former merely looks at the file extension while the later use the actual contents of the file.

Okay, I see. Nevertheless, I had some issues with this line:

const { mime } = makeSynchronous(() => fileType.fromBuffer(fileData))();

I did not see any errors in the logs but for some weird reason the default electron window opened.

@Nokel81
Copy link
Collaborator Author

Nokel81 commented Aug 19, 2020

fair, let me take a look

@nevalla nevalla closed this Aug 20, 2020
@nevalla nevalla reopened this Aug 20, 2020
@Nokel81 Nokel81 changed the base branch from vue_react_migration to master August 20, 2020 13:01
@Nokel81
Copy link
Collaborator Author

Nokel81 commented Aug 20, 2020

@nevalla changed to base master

package.json Outdated
@@ -184,6 +185,7 @@
"jsonpath": "^1.0.2",
"lodash": "^4.17.15",
"mac-ca": "^1.0.4",
"make-synchronous": "^0.1.0",
Copy link
Member

Choose a reason for hiding this comment

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

Why do we need this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Because file-type is async only but migrations have to be sync only

package.json Outdated
@@ -184,6 +185,7 @@
"jsonpath": "^1.0.2",
"lodash": "^4.17.15",
"mac-ca": "^1.0.4",
"make-synchronous": "https://github.com/Nokel81/make-synchronous#e366285001da13f4d5c028888a56b9baf83f9cff",
Copy link
Member

Choose a reason for hiding this comment

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

Why not from npm? Btw maybe we could support async migration and avoid this to overcomplicating simple things?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was temporary because I had made some changes that had not yet been merged upstream to this package. A comparable fix has now been published, so I will change back.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We cannot support async migration because the library that we use doesn't support it at all

Comment on lines +12 to +14
const AsyncFunction = Object.getPrototypeOf(async function () { return }).constructor;
const getFileTypeFnString = `return require("file-type").fromBuffer(fileData)`;
const getFileType = new AsyncFunction("fileData", getFileTypeFnString);
Copy link
Member

Choose a reason for hiding this comment

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

This looks crazy to my eyes.. What have you tried to achieve with this? Why evaluating JS-string?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fair, I am just going to say fair since this was annoying to get right.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is needed for several things:

  1. webpack is used which mucks with require and await import so we need someway to deal with that. There is __non_webpack_require__ but that only exists when webpack is being used (which it is not during tests)
  2. It cannot be just a normal eval since the type that make-synchronous uses is AsyncFunction
  3. AsyncFunction is not a global and I got that first line from mozilla's web docs.

const migratedClusters: ClusterModel[] = []
const storedClusters: ClusterModel[] = store.get("clusters");
const kubeConfigBase = path.join((app || remote.app).getPath("userData"), "kubeconfigs")
const userDataPath = (app || remote.app).getPath("userData")
Copy link
Member

Choose a reason for hiding this comment

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

I'm wondering is it even possible to stop using remote.app in runtime at some point and still support it in migrations?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Dunno, I just wanted to call this once, since it is used in many places.

@Nokel81 Nokel81 requested a review from nevalla August 21, 2020 14:38
Sebastian Malton added 7 commits August 21, 2020 10:39
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
…-type package

Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Signed-off-by: Sebastian Malton <smalton@mirantis.com>
Copy link
Contributor

@nevalla nevalla left a comment

Choose a reason for hiding this comment

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

Migration seems to work now correctly

@nevalla nevalla added this to the 3.6.0 milestone Aug 25, 2020
@nevalla nevalla added the bug Something isn't working label Aug 25, 2020
@nevalla nevalla merged commit a12aa8a into lensapp:master Aug 25, 2020
preferences: {
terminalCWD: "/tmp"
}
},
})
}),
"icon_path": testDataIcon,
Copy link
Member

Choose a reason for hiding this comment

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

How does it work? testDataIcon should be a Buffer type?

@@ -6,6 +6,10 @@ import { ClusterStore } from "./cluster-store";
import { workspaceStore } from "./workspace-store";
import { saveConfigToAppFiles } from "./kube-helpers";

const testDataIcon = fs.readFileSync("test-data/cluster-store-migration-icon.png")
Copy link
Member

@ixrock ixrock Aug 27, 2020

Choose a reason for hiding this comment

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

Can we remove it or at least move to __mocks__ or src/migrations folder?

@nevalla nevalla mentioned this pull request Aug 28, 2020
@nevalla nevalla mentioned this pull request Sep 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants