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

Development environment with hot reloading #221

Merged
merged 4 commits into from
Jul 31, 2019

Conversation

dpordomingo
Copy link
Contributor

@dpordomingo dpordomingo commented Jul 21, 2019

fix src-d/sourced-ce#26
blocked by src-d/sourced-ce#158

The current way to develop the UI is very painful:

  • make build takes ~10 mins every time you run it after changing some CSS line (because it ruins the cached docker context)
  • the official way is not clearly documented and is affected by the changes we made in superset because source{d} CE. It is needed extra wiring to run it.

This PR proposes a new way to run an environment for development (in MacOS and Linux), running (see docs in the CONTRIBUTING.md):

$ make dev-prepare
$ sourced init local

If it is done in that way, the env takes ~2mins to be ready, and every hot-reload takes ~5sec or less.

TL;DR

  • You'll find below the rationale behind the decision made.
  • Core changes in this PR
    • 1dc63ed Configure development environment with hot reloading
    • 597842d Polish README.md, moving info to CONTRIBUTING.md
  • Some other things that could be done in a separated PR if you prefer so:
    • 95de302 Remove make dev-patch; I didn't find a use-case now that we have this, wdyt?
    • f32cd19 Restore superset/contrib/docker/docker-init.sh (unused since we joined init scripts)

More info

When incubator-superset is ran in development mode, it's usually started with local directories bound to some internal paths. Content from volumes —in linux—, is owned by the user from the host machine.
Since the incubator-superset container is built to be run with superset user, content from volumes might be not writable because superset user is not the owner of those mounted dirs (as described by apache/superset#6887).

Alternatives:

Run incubator-superset as root:

  • since it's not the expected way to run superset, it can be unexpected,
  • data which is written in the volumes (as node_modules or __pycache__) will be written as root, so it won't be writable from the host machine (without being root)

Run incubator-superset container as root, but run incubator-superset app with the user owning the bound data; to do so:

  1. assumption: all the bound data is owned by the same user.
  2. Change the UID of superset, to the UID of the owner of the bound data.
  3. Make sure the entrypoint is run by superset user, owning the original container data and the data bound to directories in the host machine.
  4. All the data written by superset, will use the UID of the user of the host, so it will be writable also by that user in the host.

Docker loads (by default) an extra docker-compose.override.yml file (docs multiple-compose-files), with that in mind, we can extend our official docker-compose.yml file with our custom config to let the user run source{d} CE in development mode with hot reloading.

@dpordomingo dpordomingo added the enhancement New feature or request label Jul 21, 2019
@dpordomingo dpordomingo requested review from ricardobaeta and a team July 21, 2019 16:43
@dpordomingo dpordomingo self-assigned this Jul 21, 2019
@dpordomingo
Copy link
Contributor Author

I tested an initial version of this PR in MacOS successfully, but I need to try again the chmod thing.
I will try it and confirm it here when done.

@dpordomingo
Copy link
Contributor Author

@ricardobaeta this version should be way easier to run than the one you tried some weeks ago.

exit 1
fi

make --no-print-directory apply-patch
Copy link
Contributor

Choose a reason for hiding this comment

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

you listen for delete event but doesn't delete anything

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good catch...
I don't want to process the event to remove files on the other side...
Do you think that would it be safe calling git clean -fd $(SUPERSET_DIR) while the developer is working there?
(I'm not used to this git clean, so I'm not sure if some changes in $(SUPERSET_DIR) could be lost because of the git clean)

If it is not, I'd just exclude the delete event, and document:

Elements deleted in srcd won't be deleted from sourced; you can stop the watcher and call it again instead.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't feel comfortable if something can remove my work without my explicit action.
So I don't think git clean is a good solution here.

Keeping stuff can cause SUPER WEIRD behavior. For example, a user does import from 'path/*' somewhere.

Can we just call rm if we received the event?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Well.... import *... sigh

I should dig more on how the delete event is logged (and also the move event, if it's different...) considering the different platforms...

What if it could be done in a separate PR, and documented in the meantime?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

issue opened to be done separately #225

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just call rm if we received the event?

This shouldn't be hard, and it seems sensible and the most straightforward thing to do IMHO, isn't it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Each watcher returns the detected changes in a different way, so it should be parsed the output in both cases.
Since it is not critical, and it's documented, I think we can merge and improve later,

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay! Thanks for the explanation!

version: '3.2'
services:
sourced-ui:
user: 0:0
Copy link
Contributor

Choose a reason for hiding this comment

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

what does it do?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It runs the container as root, instead of as superset (the user inside, not the host one)

The reasoning is detailed in the PR description, section: "More info" (it is also added a link to an issue in Superset repo)

Copy link
Contributor

Choose a reason for hiding this comment

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

YAML supports comments, let's add short description there. Something like set user as root inside the container to allow writing on host filesystem

Copy link
Contributor Author

Choose a reason for hiding this comment

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

well... that's not (fully) true, at least not directly. The whole sentence should be something like:

Set user as root inside the container to change superset internal UID to be the same as the host user. It will provide write access to the data from the volumes inside and outside of the container.

The problem is that the user: 0:0 is not enough to "allow writing on host filesystem".
The user: 0:0 is (only) needed to change internal superset UID, and then run the /entrypoint.sh as superset, which will do provide the write access.

But if you feel comfortable with that other doc as you proposed, let's do it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

docs added by d3dbe90

Makefile Show resolved Hide resolved
@dpordomingo dpordomingo force-pushed the dev-hot-reloading branch 2 times, most recently from bc5db1c to 1eff7f6 Compare July 29, 2019 17:02
@dpordomingo
Copy link
Contributor Author

dpordomingo commented Jul 29, 2019

I tested make dev-prepare in OSX and it's now working thanks to the new commit d14273d

  • Avoid UID hack on OSX -> as described in PR desc, there's no problem with UID on OSX
  • Replace sed with awk -> because arguments in BSD sed and GNU sed are different
  • Adapt how stat command is formatted in BSD
  • Adapt how the colors are requested in BSD and GNU echo

This is now ready for final validation @src-d/applications

@dpordomingo dpordomingo requested review from a team and smacker July 29, 2019 17:08
Makefile Outdated Show resolved Hide resolved
Makefile Outdated Show resolved Hide resolved
@@ -27,8 +40,8 @@ elif [ "$SUPERSET_ENV" = "development" ]; then
celery worker --app=superset.sql_lab:celery_app --pool=gevent -Ofair &
# needed by superset runserver
(cd superset/assets/ && npm ci)
(cd superset/assets/ && npm run dev) &
FLASK_ENV=development FLASK_APP=superset:app flask run -p 8088 --with-threads --reload --debugger --host=0.0.0.0
(cd superset/assets/ && npm run dev-server -- --host=0.0.0.0 --port=8088 --supersetPort=8081) &
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please add a comment or explain how the ports here are being used? In particular port 8081.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's explained in their docs apache/incubator-superset/CONTRIBUTING.md#building and it might be too much to explain this wiring... but let's try; wdyt about 885dad2?

watcher Outdated Show resolved Hide resolved
watcher Outdated Show resolved Hide resolved
watcher Outdated Show resolved Hide resolved
exit 1
fi

make --no-print-directory apply-patch
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we just call rm if we received the event?

This shouldn't be hard, and it seems sensible and the most straightforward thing to do IMHO, isn't it?

CONTRIBUTING.md Outdated Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
CONTRIBUTING.md Outdated Show resolved Hide resolved
@dpordomingo
Copy link
Contributor Author

Thanks, @carlosms
your suggestions were addressed by 22e22a2

@dpordomingo dpordomingo requested a review from carlosms July 30, 2019 16:09
- Add docs (CONTRIBUTING.md)
- Add command: 'make set-override'
- Add 'docker-compose.override.yml' to override sourced 'docker-compose.yml'
- Add 'watcher' command
- Change 'docker-entrypoint.sh' to:
  - (in Linux) Accept 'root' user, and swipe to the expected 'superset' user.
  - Serve the UI from 'webpack-dev-server' instead of 'flask'.

Signed-off-by: David Pordomingo <[email protected]>
Since 'make patch-dev' is no longer needed, we can get rid of it, and
also delete 'srcd/superset/superset_config_dev.py'

Signed-off-by: David Pordomingo <[email protected]>
@dpordomingo dpordomingo merged commit 9ff32db into src-d:master Jul 31, 2019
@dpordomingo dpordomingo deleted the dev-hot-reloading branch July 31, 2019 18:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add docs to build from sources
4 participants