reactioncommerce / reaction

Mailchimp Open Commerce is an API-first, headless commerce platform built using Node.js, React, GraphQL. Deployed via Docker and Kubernetes.
https://mailchimp.com/developer/open-commerce/
GNU General Public License v3.0
12.34k stars 2.17k forks source link

Product Variant Options Not Displayed #1811

Closed cooperstevenson closed 7 years ago

cooperstevenson commented 7 years ago

For bugs, please fill out the three following sections completely

Expected behavior

Product variant options such as weight, quantity, price, etc. should display when editing a product's variants. Behavior exhibited in both Chromium and Firefox.

Actual Behavior

No product variant options appear.

Steps to Reproduce the Behavior

  1. Build fresh docker containers with the following docker-compose.yml

docker-compose.yml file contents

version: '2' services: nginx-proxy: image: jwilder/nginx-proxy:latest container_name: nginx-proxy volumes:

  • /etc/letsencrypt/live/yourhost.yourdomain.com:/opt/certs:ro
  • /etc/nginx/vhost.d
  • /usr/share/nginx/html
  • /var/run/docker.sock:/tmp/docker.sock:ro
  • /etc/nginx/conf.d/my_proxy.conf:/etc/nginx/conf.d/my_proxy.conf:ro ports:
  • "80:80"
  • "443:443" environment: VIRTUAL_HOST: "yourhost.yourdomain.com"

    lets-encrypt: image: jrcs/letsencrypt-nginx-proxy-companion:latest container_name: lets-encrypt volumes_from:

  • nginx-proxy volumes:
  • /etc/letsencrypt/live/market.ilwacofish.com:/opt/certs:rw
  • /var/run/docker.sock:/var/run/docker.sock:ro

    reaction: image: reactioncommerce/reaction:latest build: https://github.com/reactioncommerce/reaction.git links:

  • mongo ports:
  • "3000" environment: ROOT_URL: "http://yourhost.yourdomain.com" MONGO_URL: "mongodb://mongo:27017/meteor" REACTION_EMAIL: "you@yourdomain.com" MAIL_URL: "smtp://you%40yourdomain.com:yourpassword@smtp.gmail.com:465" REACTION_USER: "admin" REACTION_AUTH: "your_reaction_password" VIRTUAL_HOST: "yourhost.yourdomain.com" LETSENCRYPT_EMAIL: "youremail@yourdomain.com" LETSENCRYPT_HOST: "yourhost.yourdomain.com" mongo: image: mongo:latest ports:
  • "27017:27017" command: mongod --storageEngine=wiredTiger

NOTE: this issue presents itself regardless of building from image (reactioncommerce/reaction:latest) or from a build (https://github.com/reactioncommerce/reaction.git)

Here is the error from Chromium's console:

2c808ae….js?meteor_js_resource=true:162 XHR finished loading: GET "http://yourdomain.com/cfs/servertime". h.call @ 2c808ae….js?meteor_js_resource=true:162 h.get @ 2c808ae….js?meteor_js_resource=true:162 (anonymous) @ 2c808ae….js?meteor_js_resource=true:353 s @ 2c808ae….js?meteor_js_resource=true:3 u @ 2c808ae….js?meteor_js_resource=true:3 2c808ae….js?meteor_js_resource=true:143 XHR finished loading: GET "http://yourdomain.com/sockjs/info? cb=qlxtx1827r". y._start @ 2c808ae….js?meteor_js_resource=true:143 (anonymous) @ 2c808ae….js?meteor_js_resource=true:143 2c808ae….js?meteor_js_resource=true:3 Exception from Tracker recompute function: 2c808ae….js?meteor_js_resource=true:3 Error: Unexpected object in htmljs in toText: Label at t.visitObject (2c808ae….js?meteor_js_resource=true:183) at t.visit (2c808ae….js?meteor_js_resource=true:183) at Object.o.toText (2c808ae….js?meteor_js_resource=true:183) at Object.h._toText (2c808ae….js?meteor_js_resource=true:185) at h.View.d (2c808ae….js?meteor_js_resource=true:185) at 2c808ae….js?meteor_js_resource=true:185 at Function.e._withTemplateInstanceFunc (2c808ae….js?meteor_js_resource=true:186) at 2c808ae….js?meteor_js_resource=true:185 at Object.h._withCurrentView (2c808ae….js?meteor_js_resource=true:185) at n (2c808ae….js?meteor_js_resource=true:185)

Here is a screenshot:

variant

cooperstevenson commented 7 years ago

Update: I paired the configuration (docker-compose.yml) down to it's base elements:

reaction:
  image: reactioncommerce/reaction:latest
  links:
    - mongo
  ports:
    - "80:3000"
  environment:
    ROOT_URL: "http://yourhost.yourdomain.com"
    MONGO_URL: "mongodb://mongo:27017/meteor"
    REACTION_EMAIL: "you@yourdomain.com"
    MAIL_URL: "smtp://you%40yourdomain.com:yourpass@smtp.gmail.com:465"
    REACTION_USER: "admin"
    REACTION_AUTH: "your.email.password"
    VIRTUAL_HOST: "yourhost.yourdomain.com"

mongo:
  image: mongo:latest
  command: mongod --storageEngine=wiredTiger

Here is the script I use to completely destroy the docker containers and instances for a fresh build:

#!/bin/bash

# Stop all containers
docker stop $(docker ps -a -q)

# Delete all containers
docker rm $(docker ps -a -q)

# Delete all images
docker rmi $(docker images -q)
jshimko commented 7 years ago

FYI, multi-line code blocks should be surrounded by 3 backticks (```) on either end of the block. I fixed your comment (click the pencil icon to edit it and view the source)

cooperstevenson commented 7 years ago

Yeah, I believe the 'code' button needs fixing--when the user clicks it it displays only two backticks in the edit box and places the cursor between them.

This made the code look terrible so I used the "quote" wiki entry. For example, if I write the three backticks as you suggest I get this:

# Absolutely incredible code
for i in incredible_code
do
  print "Incredible message."
done

If, on the other hand, I click the "code button" I get this (all other formatting remains the same):

# Absolutely incredible code for i in incredible_code do print "Incredible message." done

If the user is not familiar with this particular Wiki's format (three backticks) they will not know how to correctly format their code.

It's not your fault and I "get" why the second example formats the way it does. Still, the parser ought to be smart enough to see that the user is entering multi-line code, or at least have a "multi-line code" button.

Either way, thanks for your patience about the inconvenience.

jshimko commented 7 years ago

It's all just standard Markdown formatting. The ``` for multi-line blocks isn't a Github thing. Only the specific colors in the syntax highlighting is.

https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#code

And the button you're talking about is for inline code, not multi-line blocks. It adds two backticks and puts your cursor between them. That's for things like this.

cooperstevenson commented 7 years ago

How embarrassing--it feels like my slip is showing. :) Thanks for the pro-tip.

jshimko commented 7 years ago

No worries. We all had to figure it out at some point. :)

So anyway... this is a known issue and has been fixed in release-0.19.0 (which has a ton of UI/UX updates). It should be getting releases soon, but if you'd like to test the new release now, you can run:

reaction init -b release-0.19.0
cooperstevenson commented 7 years ago

I'm saddened to report that, presuming I performed the upgrade correctly, the suggestion to update to release-0.19.0 does not work, at least in my case.

I destroyed all containers and images (as described by my script above).

I then modified the 'build' statement in my docker-compose.yml file to the following:

build: https://github.com/reactioncommerce/reaction.git#release-0.19.0

A docker-compose up command built fresh reaction and mongo instances.

Here is a screen capture of the system after a fresh rebuild from release 0.19.0:

screen

jshimko commented 7 years ago

Can you please try a local development copy first? It works fine for everyone else at this point. And I tested it right before I suggested you try it.

cooperstevenson commented 7 years ago

Hi Jeremy,

You bet, I'm happy to. Doing...

cooperstevenson commented 7 years ago

Hi Jeremy,

Works like a charm. I executed thus on my local workstation:

[I] cstevens@plato ~/src> sudo npm install -g reaction-cli
[I] cstevens@plato ~/src> reaction init -b release-0.19.0

By which the system responded thusly (of course):

Cloning the release-0.19.0 branch of Reaction from Github...
Cloning into 'reaction'...

Installing NPM packages...
npm WARN deprecated node-uuid@1.4.7: use uuid module instead

[I] cstevens@plato ~/src> cd reaction
[I] cstevens@plato ~/s/reaction> reaction

Using settings file at settings/dev.settings.json

Setting up plugin imports...

Setting up style imports...

[[[[[ ~/src/reaction ]]]]]

=> Started proxy.
=> Started MongoDB.

cfs:gridfs: updating npm dependencies -- mongodb, gridfs-stream...
19:38:22.652Z  INFO Reaction: Load default data from /private/data/
19:38:22.837Z  INFO Reaction: JobServer started
19:38:22.839Z  WARN Reaction: Skipped loading settings from reaction.json.
19:38:25.590Z  INFO Reaction: Using meteor --settings to create admin user
19:38:27.116Z  WARN Reaction:

   *********************************

    IMPORTANT! DEFAULT ADMIN INFO

    EMAIL/LOGIN: asrrrdnb@localhost

    PASSWORD: p-VOQBvu

   *********************************

19:38:27.156Z  WARN Reaction: OpenExchangeRates API not configured. Not adding fetchRates job
19:38:27.157Z  WARN Reaction: OpenExchangeRates API not configured. Not adding flushRates job
19:38:27.311Z  INFO Reaction: Reaction initialization finished.
=> Started your app.

=> App running at: http://localhost:3000/

I run the app from http://localhost:3000 and see the following:

screen

So (of course), there's something going on between a local build and a build with docker-compose (presumably through docker also though I'm not certain, really) on a remote server.

From the outside looking in I would say this is either a) something not running as part of reaction init as part of the build or b) some kind of communications issue over the internet.

I note that I cannot run reaction init and friends from the container as the container does not have a reaction executable inside it.

To test, simply destroy all container instances and images from the remote server. Then, from a directory containing your docker-compose.yml (outlined below), simply run docker-compose up.

  reaction:
      build: https://github.com/reactioncommerce/reaction.git#release-0.19.0
       links:
      - mongo
    ports:
      - "80:3000"
    environment:
      ROOT_URL: "http://host.yourdomain.com"
      MONGO_URL: "mongodb://mongo:27017/meteor"
      REACTION_EMAIL: "you@yourdomain.com"
      MAIL_URL: "smtp://you%40yourdomain.com:yourpass@smtp.gmail.com:465"
      REACTION_USER: "admin"
      REACTION_AUTH: "your.password"
      VIRTUAL_HOST: "host.domain.com"
  mongo:
    image: mongo:latest
    command: mongod --storageEngine=wiredTiger

If you like I can test running docker containers on localhost.

Also, I'm happy to give you admin privileges on a freshly-built instance. I can even provide you with a login to the server. Consider it perhaps a "fresh, ready-made" development environment if you like.

I hope this helps.

cooperstevenson commented 7 years ago

Hi Erik,

Can I help test this ticket?

Best,

-Cooper

On 02/21/2017 12:15 PM, Erik Kieckhafer wrote:

Reopened #1811 https://github.com/reactioncommerce/reaction/issues/1811.

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/reactioncommerce/reaction/issues/1811#event-971401004, or mute the thread https://github.com/notifications/unsubscribe-auth/AA0CAORTmw4djmVaOpP8gjQRNf4XgYhwks5re0XhgaJpZM4L7YDO.

aaronjudd commented 7 years ago
basic_reaction_product

I'm unable to reproduce, testing with https://hub.docker.com/r/reactioncommerce/prequel/

aaronjudd commented 7 years ago

btw @jshimko I tried to test this custom build, because out of curiosity - I have not used that feature of compose, but the build fails.

reaction:
  build: https://github.com/reactioncommerce/reaction.git#development
  links:
    - mongo
  ports:
    - "3050:3000"
  environment:
    ROOT_URL: "http://localhost:3000"
    MONGO_URL: "mongodb://mongo:27017/reaction"

mongo:
  image: mongo:latest
  command: mongod --storageEngine=wiredTiger

dies with the classic

Error: EXDEV: cross-device link not permitted, rename '/opt/reaction/src/packages/gridfs/.npm/package' -> '/opt/reaction/src/packages/gridfs/.npm/package-garbage-k1i8ln'
    at Error (native)

while building Meteor.

cooperstevenson commented 7 years ago

Hi Aaron,

Are you starting from a fresh virtual instance? Would you mind outlining the steps? I followed the steps from the page in your reply and found the same Edit Variant issue across multiple client browsers and operating systems.

Best & Thanks,

-Cooper

cooperstevenson commented 7 years ago

Hi Aaron,

I took another look at your screen capture and note that the instance depicted is running on localhost. Yes, Reaction does work fine when deployed to localhost. This bug report relates to accessing the system deployed on a remote host.

NOTE: I created a handy script at the bottom of this post that clears the server fresh, pulls the docker repository, and starts the Reaction instance.

Step-by-step Install Process

In order to reproduce this issue, deploy and access via a remote server as I've outlined here. The commands are run on the remote host unless otherwise indicated:

#!/bin/bash

# Stop all containers
docker stop $(docker ps -a -q)
# Delete all containers
docker rm $(docker ps -a -q)
# Delete all images
docker rmi $(docker images -q)
# Delete all hanging volumes
docker volume ls -f dangling=true | awk '{print $2}' | while read i
do 
  docker volume rm $i 
done
  1. Make sure all mongo databases are clear as outline here (run from the mongo shell). This step assumes that you are running mongo from either a) the main host instance or b) a remote instance. Modify the command as appropriate. If you are running mongo from the docker build you may safely ignore this step:
use [database];
db.dropDatabase();
  1. Create Dockerfile directory
mkdir -p /var/www/html/market/docker
  1. Create the link. The Docker file will be a link to docker/reaction.dev.docker as outlined below:
root@market:/var/www/html/market# ln -s /var/www/html/market/docker/reaction.dev.docker /var/www/html/market/Dockerfile
  1. Create the Docker file:

    FROM reactioncommerce/prequel
        ENV ROOT_URL: "http://your.domain"
        ENV MONGO_URL "mongodb://127.0.0.1:27017/reaction"
        ENV REACTION_EMAIL: "email@your.domain"
        ENV MAIL_URL: "smtp://email%40yourdomain.com:password@smtp.gmail.com:465"
        ENV REACTION_USER: "admin_username"
        ENV REACTION_AUTH: "admin_password"
        ENV VIRTUAL_HOST: "host.yourdomain.com"
  2. Pull the repository

    root@market:/var/www/html/market# docker pull reactioncommerce/prequel
  3. Build the repository

    root@market:/var/www/html/market# docker build -t reaction .
  4. Run The instance:

root@market:/var/www/html/market# docker run --rm \
-p 80:3000 \
-e ROOT_URL="http://yourhost.yourdomain.com" \
-e REACTION_EMAIL="you@yourhost.com" \
-e REACTION_USER="your_admin_user" \
-e REACTION_AUTH="your_admin_password" \
-t reaction
  1. From here you can authenticate the admin's email address with the link provided by Reaction's build process:
    ***************************************************
            IMPORTANT! EMAIL VERIFICATION LINK

             Email sending is not configured.

    Go to the following URL to verify email: you@yourdomain.com

    http://host.yourdomain.com/#/verify-email/vAd4c6RhCrPtsOkT-P4p8Gi-ymDSf51nLAkH5W599eJ
    ***************************************************

17:51:42.613Z  WARN Reaction: Reaction.Email.getMailUrl() - no email provider configured
17:51:42.624Z ERROR Reaction: Mail not configured
17:51:44.201Z  WARN Reaction:

   *********************************

    IMPORTANT! DEFAULT ADMIN INFO

    EMAIL/LOGIN: you@your_domain.com

    PASSWORD: your_password

   *********************************
  1. Verify email with the link provided and log in.

  2. Click on the 'Basic Reaction Product' and attempt to edit the product's variant. This will fail:

reaction

Reaction Build Script

WARNING: This script will destroy all your docker instances and delete your docker volumes

#! /bin/bash

# Build New reaction instance

#TODO: set variable for branch (i.e. latest, prequel, etc.)

# make sure the mongo instance is up
# service mongo start

# Pull the prequil instance
docker pull reactioncommerce/prequel

# Build the instance
docker build -t reaction .

# Run the instance:
# docker run -p :8080 -it reaction

# Run the instance:
docker run --rm \
-p 80:3000 \
-e ROOT_URL="http://host.yourdomain.com" \
-e REACTION_EMAIL="you@yourdomain.com" \
-e REACTION_USER="admin_user_name" \
-e REACTION_AUTH="admin_password" \
-t reaction
jshimko commented 7 years ago

@cooperstevenson I think your issues here may be due to a few minor misunderstandings about how Docker works.

A couple things...

First, why are you going through the steps of creating a new Dockerfile and using reactioncommerce/prequel as a base image? You're not customizing the base image, so that step isn't necessary. That's just pulling the image and hard coding the environment variables into your newly built image (which you are then overwriting several of those variables when you do the docker run command). That's a lot of redundant steps that can be boiled down to a single command without having to create files, do a build step, or manage a database on your host:

docker run -d \
  -p 80:3000 \
  -e REACTION_EMAIL="me@example.com" \
  -e REACTION_USER="admin" \
  -e REACTION_AUTH="admin" \
  -e ROOT_URL="http://yourdomain.com"
  reactioncommerce/prequel:latest

That consistently works fine for me every time - locally or on a remote server. And when I go to edit the variant (like your screenshot above), everything looks like it should.

basic_reaction_product_and_config_json_ ____reaction

So I still can't reproduce your problem.

And I don't follow why you're doing all of those mongo steps on your host. You're not actually using that database anywhere in your examples. When you set MONGO_URL to mongodb://127.0.0.1:27017/reaction inside your container, 127.0.0.1 is inside the Docker container, not on the Docker host itself. So your example above is using the built-in Mongo inside the container.

So, using all of the environment variables in your example, a full working reproduction in a single command would look like this:

docker run -d \
  -p 80:3000 \
  -e ROOT_URL="http://yourdomain.com" \
  -e MONGO_URL="mongodb://some-external-domain.com:27017/reaction" \
  -e MAIL_URL="smtp://email%40yourdomain.com:password@smtp.gmail.com:465" \
  -e REACTION_EMAIL="me@example.com" \
  -e REACTION_USER="myusername" \
  -e REACTION_AUTH="mypassword" \
  reactioncommerce/prequel:latest

Or to just test it without needing an external database:

docker run -d \
  -p 80:3000 \
  -e ROOT_URL="http://yourdomain.com" \
  -e MAIL_URL="smtp://email%40yourdomain.com:password@smtp.gmail.com:465" \
  -e REACTION_EMAIL="me@example.com" \
  -e REACTION_USER="myusername" \
  -e REACTION_AUTH="mypassword" \
  reactioncommerce/prequel:latest

Or the absolute minimum amount of options to start an app instance:

docker run -d -p 80:3000 reactioncommerce/prequel:latest

Or the full config using Docker Compose instead:

reaction:
  image:  reactioncommerce/prequel:latest
  links:
    - mongo
  ports:
    - 80:3000
  environment:
    ROOT_URL: "http://yourdomain.com" 
    MONGO_URL: "mongodb://some-external-domain.com:27017/reaction" 
    MAIL_URL: "smtp://email%40yourdomain.com:password@smtp.gmail.com:465" 
    REACTION_EMAIL: "me@example.com" 
    REACTION_USER: "myusername" 
    REACTION_AUTH: "mypassword" 

mongo:
  image: mongo:latest
  command: mongod --storageEngine=wiredTiger
docker-compose up -d
jshimko commented 7 years ago

This was also unintentionally reopened 6 days ago, so I'm going to close it for now as it appears to be an implementation issue and not an issue with the project itself. Certainly feel free to reopen it if you are able to identify a reason why that may not be the case.

cooperstevenson commented 7 years ago

Hi Jeremy,

The long and short of it: I knew that I didn't need to destroy the instances, etc. I did this as I have an "administrator's mentality." That is, anytime I consider putting a system into production I have to pretend I'm coming in from fresh iron. This way, in case of hardware failure or (more likely) an inexperienced administrator striking the wrong key I can recover quickly.

In this case, I should be able to bring a Reaction instance up with a single script pulling from hourly backups. I have too--I can't responsibly put a system into production without solid disaster recovery and redundancy.

Anyway, yes, this is an issue. To uncover it you need to go out to a fresh VM and/or blow away any trace of Reaction and build an instance from scratch. I would not make this bold claim had I not tested the theory extensively.

Okay. So I tracked the issue down to the ROOT_URL variable. If you heat up a fresh container--having had no other containers or Mongo reaction databases on that system from the start--with a ROOT_URL as one of docker-run's environment variables you will not get the products' variant panel to display. Every. Time.

If you then blow everything away (especially the mongo database) and perform a docker run without the ROOT_URL environment variable you will see the product's variants. Every. Time.

So the trick is to first heat up a Reaction instance (again, sans-ROOT_URL environment variable), stop the docker container, and then docker run with the same environment variables as before...only this time add the ROOT_URL environment variable.

It's as if the initialization system works well when working with localhost but fails when running with a fully qualified host name as it's ROOT_URL, "right out of the gate."

The bug is masked probably as each of the machines this has been tested on so far has always had an initial docker run using localhost as it's ROOT_URL.

So, when you add the FQHN on the second run the Reaction initialization seems to do this 'rsync' thing where it keeps the rest of the initialization settings from the previous localhost run; the second docker run seems to only modify the newer ROOT_URL parameters.

Here's some pseudo-admin code:

  1. docker run -e your_variables_except_ROOT_URL 1.5 Watch as everything works except Reaction's emails show something like 'http://localhost/reaction...'
  2. docker stop container
  3. docker run -e your_variables_with_ROOT_URL
  4. Happy times. The system sees the variants and Reaction's emails show the correct base URL.

They key to uncovering this gremlin is starting with a fresh vm, i.e. having to install mongo, docker, "the works."

Finally, I want to thank all of your team for all your efforts. If you would like me to test anything (with a jaded Administrator's eye) please let me know!

jshimko commented 7 years ago

Thanks for taking the time to write all of this out @cooperstevenson. I can confirm that the ROOT_URL deal is definitely true. Nice catch.

I can also confirm that it's only with a production build. Setting a ROOT_URL in development does not cause the same issue (which sucks because that means we have to trace it back in minified code).

That said, the error is a familiar one (although I don't remember how it went away last time). You should see this and a stack trace in your browser console:

Error: Unexpected object in htmljs in toText: Label
...

which appears to be happening in the productDetailForm Blaze template. My first guess is i18n translation of a label, but @mikemurray thinks it may be related to Autoform.

We'll dig a little and see what we can figure out. Thanks again for your efforts.

cooperstevenson commented 7 years ago

You already know this though I'll confirm the stack trace. Yes, the Error: Unexpected object in htmljs in toText: Label is the error I receive also.

kieckhafer commented 7 years ago

We will re-verify issue in 0.19.1

This only occurs when you set an alternate ROOT_URL

aaronjudd commented 7 years ago

Should be able to reproduce locally by adding an entry to /etc/hosts, then export ROOT_URL="hosts entry domain", then start reaction with an alternate port --port.

mikemurray commented 7 years ago

The issue seems to be i18n helper on the placeholder attributes for the autoform fields in variantForm.js

placeholder=(i18n "productVariant.taxDescription" "Tax Description")
jshimko commented 7 years ago

I've confirmed #1976 fixes it in every scenario it was broken in.

jshimko commented 7 years ago

The fix has been merged into development.