diff --git a/.gitignore b/.gitignore index 3fe881fd..9ae0bf9e 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ configs dist .m2 .venv +.vagrant diff --git a/Vagrantfile b/Vagrantfile index 226f417a..edf68b02 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -2,10 +2,11 @@ # vi: set ft=ruby : # Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ # +# ================== # Bubble Vagrantfile # ================== -# `vagrant up` will create a full Bubble development environment, and optionally start -# a local launcher. +# Running `vagrant up` will create a full Bubble development environment, and +# optionally start a local launcher. # # ## Environment Variables # @@ -20,10 +21,10 @@ # Set the `BUBBLE_PORT` environment variable to another port, and Bubble will listen on # that port instead. # -# ### BUBBLE_GIT_TAG +# ### BUBBLE_TAG # By default, the Vagrant box will run the bleeding edge (`master` branch) of Bubble. -# Set the `BUBBLE_GIT_TAG` environment variable to a git branch or tag that should be -# checked out instead. +# Set the `BUBBLE_TAG` environment variable to the name of a git branch or tag to check +# out instead. # # Vagrant.configure("2") do |config| @@ -36,27 +37,38 @@ Vagrant.configure("2") do |config| # Anyone who can reach port 8090 on this system will be able to access the launcher # config.vm.network "forwarded_port", guest: 8090, host: ENV['BUBBLE_PORT'] || 8090 + config.vm.provision :shell do |s| + s.inline = <<-SHELL + apt-get update -y + apt-get upgrade -y + SHELL + end config.vm.provision :shell do |s| s.env = { LETSENCRYPT_EMAIL: ENV['LETSENCRYPT_EMAIL'], - GIT_TAG: ENV['BUBBLE_GIT_TAG'] || 'master' + BUBBLE_TAG: ENV['BUBBLE_TAG'] || 'master' } + s.privileged = false s.inline = <<-SHELL - apt-get update -y - apt-get upgrade -y - if [[ ! -d bubble ]] ; then - git clone https://git.bubblev.org/bubblev/bubble.git - fi - cd bubble - git fetch && git pull origin ${GIT_TAG} + # Get the code + git clone https://git.bubblev.org/bubblev/bubble.git + cd bubble && git fetch && git pull origin ${BUBBLE_TAG} + + # Initialize the system ./bin/first_time_ubuntu.sh - ./bin/first_time_setup.sh - if [[ -n "${LETSENCRYPT_EMAIL}" ]] ; then - echo "export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}" > bubble.env - ./bin/run.sh bubble.env + + # Clone and build all dependencies + SKIP_BUBBLE_BUILD=1 ./bin/first_time_setup.sh + + # Build the bubble jar + MVN_QUIET="" + BUBBLE_PRODUCTION=1 mvn ${MVN_QUIET} -Pproduction clean package + + # Start the Local Launcher if LETSENCRYPT_EMAIL is defined + if [[ -n \"${LETSENCRYPT_EMAIL}\" ]] ; then + echo \"export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL}\" > bubble.env + # ./bin/run.sh bubble.env fi - echo "we are in $(pwd) ok man??" - # chown -R vagrant ./* SHELL end end diff --git a/bin/bdocker b/bin/bdocker index e74c0a49..18ecc077 100755 --- a/bin/bdocker +++ b/bin/bdocker @@ -57,7 +57,7 @@ BUBBLE_SLIM_TAG="${DOCKER_REPO}/slim-launcher:${VERSION}" BUBBLE_ENV="${HOME}/.bubble.env" if [[ "${MODE}" == "build" ]] ; then - if [[ $(find bubble-server/target -type f -name "bubble-server-*.jar" | wc -l | tr -d ' ') -eq 0 ]] ; then + if [[ $(find bubble-server/target -type f -name "bubble-server-*-prod.jar" | wc -l | tr -d ' ') -eq 0 ]] ; then die "No bubble jar found in $(pwd)/bubble-server/target" fi docker build --no-cache -t "${BUBBLE_TAG}" . || die "Error building docker image" diff --git a/bin/build_dist b/bin/build_dist index 7990e6da..0ecc3ec2 100755 --- a/bin/build_dist +++ b/bin/build_dist @@ -39,7 +39,7 @@ FULL_JAR="$(find "${JAR_DIR}" -type f -name "bubble-server-*-full.jar" | head -1 if [[ -z "${FULL_JAR}" ]] ; then die "No full bubble jar found in ${JAR_DIR}" fi -JAR="$(find "${JAR_DIR}" -type f -name "bubble-server-*.jar" | grep -v full | head -1)" +JAR="$(find "${JAR_DIR}" -type f -name "bubble-server-*-prod.jar" | head -1)" if [[ -z "${JAR}" ]] ; then die "No regular bubble jar found in ${JAR_DIR}" fi diff --git a/bin/first_time_setup.sh b/bin/first_time_setup.sh index 31879c48..35917afa 100755 --- a/bin/first_time_setup.sh +++ b/bin/first_time_setup.sh @@ -18,6 +18,15 @@ # If you prefer to checkout git submodules using SSH instead of HTTPS, set the BUBBLE_SSH_SUBMODULES # environment variable to 'true' # +# Environment Variables +# +# SKIP_BUBBLE_BUILD : if set to 1, then everything will be built except for the bubble jar +# +# BUBBLE_SETUP_MODE : only used if SKIP_BUBBLE_BUILD is not set. values are: +# debug - build the bubble jar without including the website +# web - build the bubble jar, including the website +# production - build the bubble jar and the bubble full jar, both including the website +# function die() { if [[ -z "${SCRIPT}" ]] ; then @@ -55,6 +64,10 @@ for repo in ${UTIL_REPOS}; do done popd || die "Error popping back from utils directory" +if [[ -n "${SKIP_BUBBLE_BUILD}" && "${SKIP_BUBBLE_BUILD}" == "1" ]] ; then + exit 0 +fi + if [[ -z "${BUBBLE_SETUP_MODE}" || "${BUBBLE_SETUP_MODE}" == "web" ]] ; then INSTALL_WEB=web mvn ${MVN_QUIET} -Pproduction clean package || die "Error building bubble jar" diff --git a/bin/prep_bubble_jar b/bin/prep_bubble_jar index 6ebc7309..0a24e988 100755 --- a/bin/prep_bubble_jar +++ b/bin/prep_bubble_jar @@ -50,8 +50,7 @@ if [[ -n "${BUBBLE_PRODUCTION}" || ( -n "${INSTALL_WEB}" && "${INSTALL_WEB}" == else WEBPACK_OPTIONS="" fi - # Try webpack twice - cd "${BUBBLE_WEB}" && npm install && rm -rf dist/ && webpack "${WEBPACK_OPTIONS}" || webpack "${WEBPACK_OPTIONS}" || die "Error building bubble-web" + cd "${BUBBLE_WEB}" && npm install && rm -rf dist/ && webpack "${WEBPACK_OPTIONS}" || die "Error building bubble-web" cp -R "${BUBBLE_WEB}/dist"/* "${CLASSES_DIR}/site"/ || die "Error copying ${BUBBLE_WEB}/dist/* -> ${CLASSES_DIR}/site/" cd "${CLASSES_DIR}" && zip -u -r "${BUBBLE_JAR}" site || die "Error updating ${BUBBLE_JAR} with site" echo "Installed bubble-web to ${CLASSES_DIR}/site/" diff --git a/bubble-server/src/main/java/bubble/cloud/payment/delegate/DelegatedPaymentDriver.java b/bubble-server/src/main/java/bubble/cloud/payment/delegate/DelegatedPaymentDriver.java index 1fcecc69..a8275efe 100644 --- a/bubble-server/src/main/java/bubble/cloud/payment/delegate/DelegatedPaymentDriver.java +++ b/bubble-server/src/main/java/bubble/cloud/payment/delegate/DelegatedPaymentDriver.java @@ -30,7 +30,7 @@ public class DelegatedPaymentDriver extends DelegatedCloudServiceDriverBase impl log.warn("getPaymentMethodType: delegated driver has non-delegated cloud: "+cloud.getUuid()); return cloud.getPaymentDriver(configuration).getPaymentMethodType(); } - if (!configuration.paymentsEnabled()) { + if (!configuration.getPaymentsEnabled()) { log.warn("getPaymentMethodType: payments not enabled, returning null"); return null; }; diff --git a/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java b/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java index bca75f6f..84774b10 100644 --- a/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java +++ b/bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java @@ -115,7 +115,7 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO { if (errors.isInvalid()) throw invalidEx(errors); if (errors.hasSuggestedName()) accountPlan.setName(errors.getSuggestedName()); - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { if (!accountPlan.hasPaymentMethodObject()) throw invalidEx("err.paymentMethod.required"); if (!accountPlan.getPaymentMethodObject().hasUuid()) throw invalidEx("err.paymentMethod.required"); @@ -149,7 +149,7 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO { } @Override public AccountPlan postCreate(AccountPlan accountPlan, Object context) { - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { final String accountPlanUuid = accountPlan.getUuid(); final String paymentMethodUuid = accountPlan.getPaymentMethodObject().getUuid(); final BubblePlan plan = planDAO.findByUuid(accountPlan.getPlan()); @@ -191,7 +191,7 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO { networkDAO.delete(accountPlan.getDeletedNetwork()); } else { networkDAO.delete(accountPlan.getNetwork()); - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { refundService.processRefunds(); } } diff --git a/bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java b/bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java index 66aa4589..94d9f34f 100644 --- a/bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java +++ b/bubble-server/src/main/java/bubble/dao/cloud/CloudServiceDAO.java @@ -102,7 +102,7 @@ public class CloudServiceDAO extends AccountOwnedTemplateDAO { if (cloud.getType() == CloudServiceType.payment && cloud.template() && cloud.enabled() - && !configuration.paymentsEnabled()) { + && !configuration.getPaymentsEnabled()) { // a public template for a payment cloud has been added, and payments were not enabled -- now they are configuration.refreshPublicSystemConfigs(); } diff --git a/bubble-server/src/main/java/bubble/resources/account/AuthResource.java b/bubble-server/src/main/java/bubble/resources/account/AuthResource.java index 71b90caa..5c545a9b 100644 --- a/bubble-server/src/main/java/bubble/resources/account/AuthResource.java +++ b/bubble-server/src/main/java/bubble/resources/account/AuthResource.java @@ -367,7 +367,7 @@ public class AuthResource { } String currency = null; - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { currency = currencyForLocale(request.getLocale(), getDEFAULT_LOCALE()); // do we have any plans with this currency? if (!planDAO.getSupportedCurrencies().contains(currency)) { @@ -393,7 +393,7 @@ public class AuthResource { final Account account = accountDAO.newAccount(req, null, request, parent); SimpleViolationException promoEx = null; - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { if (request.hasPaymentMethod()) { final AccountPaymentMethod paymentMethodObject = request.getPaymentMethodObject(); log.info("register: found AccountPaymentMethod at registration-time: " + json(paymentMethodObject, COMPACT_MAPPER)); diff --git a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java index 58b60258..ffe46fbe 100644 --- a/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java +++ b/bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java @@ -109,12 +109,12 @@ public class AccountPlansResource extends AccountOwnedResource paymentMethods = paymentMethodDAO.findByAccountAndNotPromoAndNotDeleted(caller.getUuid()); if (empty(paymentMethods)) { @@ -296,7 +296,7 @@ public class AccountPlansResource extends AccountOwnedResource getLogFlagExpirationTime(); void setLogFlag(final boolean logFlag, @NonNull final Optional ttlInSeconds); + } diff --git a/bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java b/bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java index c47434e0..53c72ca1 100644 --- a/bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java +++ b/bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java @@ -181,7 +181,7 @@ public class StandardSelfNodeService implements SelfNodeService { } // start RefundService if payments are enabled and this is a SageLauncher - if (c.paymentsEnabled() && c.isSageLauncher() && thisNode.sage()) { + if (c.getPaymentsEnabled() && c.isSageLauncher() && thisNode.sage()) { log.info("onStart: starting BillingService and RefundService"); c.getBean(BillingService.class).start(); c.getBean(StandardRefundService.class).start(); diff --git a/bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java b/bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java index e60763b9..b7941c8d 100644 --- a/bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java +++ b/bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java @@ -50,7 +50,9 @@ import static org.cobbzilla.wizard.server.config.OpenApiConfiguration.OPENAPI_DI @Service @Slf4j public class AnsiblePrepService { - private static final int MIN_OPEN_API_MEMORY = 4096; + public static final int OPEN_API_MIN_MEMORY = 4096; + public static final int SAGE_MIN_MEMORY = 256; + public static final int NODE_MIN_MEMORY = 200; // todo: can probably go lower, need to test @Autowired private DatabaseFilterService dbFilter; @Autowired private BubbleConfiguration configuration; @@ -172,16 +174,16 @@ public class AnsiblePrepService { private int jvmMaxRam(ComputeNodeSize nodeSize, AnsibleInstallType installType) { final int memoryMB = nodeSize.getMemoryMB(); if (installType == AnsibleInstallType.sage) { - // at least 256MB, up to 60% of system memory - return Math.max(256, (int) (((double) memoryMB) * 0.6d)); + // at least a minimum of SAGE_MIN_MEMORY, up to 60% of system memory + return Math.max(SAGE_MIN_MEMORY, (int) (((double) memoryMB) * 0.6d)); } if (memoryMB >= 4096) return (int) (((double) memoryMB) * 0.6d); if (memoryMB >= 2048) return (int) (((double) memoryMB) * 0.5d); if (memoryMB >= 1024) return (int) (((double) memoryMB) * 0.24d); - // no nodes are this small, API probably would not start, not enough memory - // set floor at 200MB, might be able to go lower. - return Math.max(200, (int) (((double) memoryMB) * 0.19d)); + // API will probably not start, system will likely run out of memory + // Why are you trying to run Bubble on less than 1GB RAM? + return Math.max(NODE_MIN_MEMORY, (int) (((double) memoryMB) * 0.22d)); } private boolean shouldEnableOpenApi(AnsibleInstallType installType, ComputeNodeSize nodeSize) { @@ -189,7 +191,7 @@ public class AnsiblePrepService { // - it must already be enabled on the current bubble // - the bubble being launched must be a sage or have 4GB+ memory return configuration.hasOpenApi() && - (installType == AnsibleInstallType.sage || nodeSize.getMemoryMB() >= MIN_OPEN_API_MEMORY); + (installType == AnsibleInstallType.sage || nodeSize.getMemoryMB() >= OPEN_API_MIN_MEMORY); } } diff --git a/bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java b/bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java index b1a20bc0..1a16643e 100644 --- a/bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java +++ b/bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java @@ -454,7 +454,7 @@ public class StandardNetworkService implements NetworkService { } if (progressMeter != null) { - if (!progressMeter.success() && configuration.paymentsEnabled()) { + if (!progressMeter.success() && configuration.getPaymentsEnabled()) { final AccountPlan accountPlan = accountPlanDAO.findByNetwork(nn.getNetwork()); if (accountPlan != null) { final BubblePlan plan = planDAO.findByUuid(accountPlan.getPlan()); @@ -691,7 +691,7 @@ public class StandardNetworkService implements NetworkService { public NewNodeNotification startNetwork(BubbleNetwork network, NetLocation netLocation) { final String accountUuid = network.getAccount(); - if (configuration.paymentsEnabled()) { + if (configuration.getPaymentsEnabled()) { AccountPlan accountPlan = accountPlanDAO.findByAccountAndNetwork(accountUuid, network.getUuid()); if (accountPlan == null) throw invalidEx("err.accountPlan.notFound"); final long start = now(); diff --git a/bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java b/bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java index bb1d1c63..8e3db11f 100644 --- a/bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java +++ b/bubble-server/src/main/java/bubble/service/dbfilter/FilteredEntityIterator.java @@ -62,7 +62,7 @@ public class FilteredEntityIterator extends EntityIterator { BubbleNode node, List planApps, AtomicReference error) { - super(error, configuration.paymentsEnabled()); + super(error, configuration.getPaymentsEnabled()); this.configuration = configuration; this.account = account; this.network = network; diff --git a/bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java b/bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java index 192f77a7..0bb2eff4 100644 --- a/bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java +++ b/bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java @@ -31,7 +31,7 @@ public class FullEntityIterator extends EntityIterator { BubbleNetwork network, LaunchType launchType, AtomicReference error) { - super(error, configuration.paymentsEnabled()); + super(error, configuration.getPaymentsEnabled()); this.configuration = configuration; this.network = network; this.account = account; diff --git a/bubble-server/src/main/java/bubble/service_dbfilter/DbFilterSelfNodeService.java b/bubble-server/src/main/java/bubble/service_dbfilter/DbFilterSelfNodeService.java index 7bc406cb..cb39f1de 100644 --- a/bubble-server/src/main/java/bubble/service_dbfilter/DbFilterSelfNodeService.java +++ b/bubble-server/src/main/java/bubble/service_dbfilter/DbFilterSelfNodeService.java @@ -20,6 +20,8 @@ public class DbFilterSelfNodeService implements SelfNodeService { @Override public boolean initThisNode(BubbleNode thisNode) { return notSupported("initThisNode"); } + @Override public BubbleNode getSageNode() { return notSupported("getSageNode"); } + @Override public BubbleNode getThisNode() { return notSupported("getThisNode"); } @Override public BubbleNetwork getThisNetwork() { return notSupported("getThisNetwork"); } diff --git a/bubble-web b/bubble-web index 638ded1a..e02f50bf 160000 --- a/bubble-web +++ b/bubble-web @@ -1 +1 @@ -Subproject commit 638ded1a9f87f9a35ec997805332517a7bca85c2 +Subproject commit e02f50bf55ae38cb81846adab9904d59db6f0255 diff --git a/utils/cobbzilla-utils b/utils/cobbzilla-utils index 72e0962a..8e75e708 160000 --- a/utils/cobbzilla-utils +++ b/utils/cobbzilla-utils @@ -1 +1 @@ -Subproject commit 72e0962ac1defa342e8bad34044b56ee36817f52 +Subproject commit 8e75e7087316977e9ee3a5201ba328e62f184ffa