Преглед на файлове

allow forking a node directly from a local launcher

tags/v1.2.3
Jonathan Cobb преди 4 години
родител
ревизия
5cad7f73a4
променени са 30 файла, в които са добавени 111 реда и са изтрити 1538 реда
  1. +2
    -2
      bubble-server/src/main/java/bubble/cloud/compute/ComputeServiceDriverBase.java
  2. +9
    -3
      bubble-server/src/main/java/bubble/cloud/geoLocation/GeoLocateServiceDriverBase.java
  3. +2
    -3
      bubble-server/src/main/java/bubble/dao/account/AccountDAO.java
  4. +2
    -3
      bubble-server/src/main/java/bubble/dao/account/AccountSshKeyDAO.java
  5. +1
    -1
      bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java
  6. +1
    -1
      bubble-server/src/main/java/bubble/main/rekey/RekeyReaderMain.java
  7. +6
    -1
      bubble-server/src/main/java/bubble/model/bill/AccountPlan.java
  8. +10
    -2
      bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java
  9. +2
    -0
      bubble-server/src/main/java/bubble/model/cloud/BubbleNode.java
  10. +17
    -0
      bubble-server/src/main/java/bubble/model/cloud/LaunchType.java
  11. +3
    -0
      bubble-server/src/main/java/bubble/notify/NewNodeNotification.java
  12. +2
    -3
      bubble-server/src/main/java/bubble/notify/NotificationHandler_sync_account.java
  13. +3
    -2
      bubble-server/src/main/java/bubble/resources/account/AuthResource.java
  14. +4
    -3
      bubble-server/src/main/java/bubble/server/BubbleConfiguration.java
  15. +2
    -3
      bubble-server/src/main/java/bubble/server/listener/NodeInitializerListener.java
  16. +1
    -2
      bubble-server/src/main/java/bubble/service/account/MitmControlService.java
  17. +7
    -6
      bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java
  18. +3
    -1
      bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java
  19. +1
    -2
      bubble-server/src/main/java/bubble/service/cloud/NodeLaunchMonitor.java
  20. +4
    -3
      bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java
  21. +4
    -2
      bubble-server/src/main/java/bubble/service/dbfilter/DatabaseFilterService.java
  22. +17
    -0
      bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java
  23. +1
    -2
      bubble-server/src/main/java/bubble/service/stream/StandardAppPrimerService.java
  24. +1
    -1
      bubble-server/src/main/resources/META-INF/bubble/bubble.properties
  25. +0
    -1486
      bubble-server/src/main/resources/apps.json
  26. +1
    -0
      bubble-server/src/main/resources/db/migration/V2020091801__add_network_launch_type.sql
  27. +1
    -1
      bubble-server/src/main/resources/messages
  28. +2
    -3
      bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_api.py
  29. +1
    -1
      bubble-web
  30. +1
    -1
      utils/cobbzilla-utils

+ 2
- 2
bubble-server/src/main/java/bubble/cloud/compute/ComputeServiceDriverBase.java Целия файл

@@ -39,9 +39,9 @@ public abstract class ComputeServiceDriverBase

@Override public void postSetup() {
final String prefix = "postSetup("+getClass().getSimpleName()+"/"+cloud.getUuid()+"): ";
if (configuration.isSelfSage()) {
if (configuration.getThisNetwork().sage()) {
if (cloud.delegated()) {
log.info(prefix+"NOT starting NodeReaper for delegated driver");
log.info(prefix + "NOT starting NodeReaper for delegated driver");
} else {
synchronized (reapers) {
if (reapers.get(getCredentials()) == null) {


+ 9
- 3
bubble-server/src/main/java/bubble/cloud/geoLocation/GeoLocateServiceDriverBase.java Целия файл

@@ -10,6 +10,7 @@ import lombok.Cleanup;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.cobbzilla.util.collection.NameAndValue;
import org.cobbzilla.util.handlebars.HandlebarsUtil;
import org.cobbzilla.util.http.HttpMeta;
@@ -21,8 +22,7 @@ import org.cobbzilla.util.io.TempDir;
import org.cobbzilla.wizard.cache.redis.RedisService;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.File;
import java.io.IOException;
import java.io.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
@@ -139,9 +139,15 @@ public abstract class GeoLocateServiceDriverBase<T> extends CloudServiceDriverBa

private File downloadDbFile(HttpRequestBean request, File archive) throws IOException {
Exception lastEx = null;
if (!archive.getParentFile().exists()) {
mkdirOrDie(archive.getParentFile());
}
for (int i=0; i<MAX_FILE_RETRIES; i++) {
try {
return HttpUtil.getResponse(request).toFile(archive);
@Cleanup final InputStream in = HttpUtil.get(request.getUri(), NameAndValue.toMap(request.getHeaders()));
@Cleanup final OutputStream out = new FileOutputStream(archive);
IOUtils.copyLarge(in, out);
return archive;
} catch (Exception e) {
lastEx = e;
log.warn("downloadDbFile: "+shortError(e));


+ 2
- 3
bubble-server/src/main/java/bubble/dao/account/AccountDAO.java Целия файл

@@ -6,7 +6,6 @@ package bubble.dao.account;

import bubble.cloud.CloudServiceDriver;
import bubble.cloud.CloudServiceType;
import bubble.cloud.compute.ComputeNodeSizeType;
import bubble.dao.account.message.AccountMessageDAO;
import bubble.dao.app.*;
import bubble.dao.bill.AccountPaymentArchivedDAO;
@@ -221,8 +220,8 @@ public class AccountDAO extends AbstractCRUDDAO<Account> implements SqlViewSearc
final BubbleNetwork thisNetwork = selfNodeService.getThisNetwork();
if (parentEntity.delegated()
&& thisNetwork != null
&& thisNetwork.getInstallType() == AnsibleInstallType.node
&& thisNetwork.getComputeSizeType() != ComputeNodeSizeType.local) {
&& thisNetwork.node()
&& thisNetwork.local()) {
// on a node, sub-accounts can use the same cloud/config/credentials as their admin
return accountEntity.setDelegated(parentEntity.getDelegated())
.setCredentialsJson(parentEntity.getCredentialsJson())


+ 2
- 3
bubble-server/src/main/java/bubble/dao/account/AccountSshKeyDAO.java Целия файл

@@ -9,7 +9,6 @@ import bubble.dao.cloud.BubbleNetworkDAO;
import bubble.model.account.Account;
import bubble.model.account.AccountSshKey;
import bubble.model.bill.AccountPlan;
import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.server.BubbleConfiguration;
import lombok.extern.slf4j.Slf4j;
@@ -53,7 +52,7 @@ public class AccountSshKeyDAO extends AccountOwnedEntityDAO<AccountSshKey> {

final Account owner = accountDAO.findByUuid(key.getAccount());
final BubbleNetwork thisNetwork = configuration.getThisNetwork();
if (thisNetwork == null || thisNetwork.getInstallType() == AnsibleInstallType.sage) {
if (thisNetwork == null || thisNetwork.sage()) {
// only allow installation of a key on a sage if the user is the first admin and has no keys
final Account firstAdmin = accountDAO.getFirstAdmin();
if (owner.getUuid().equals(firstAdmin.getUuid())) {
@@ -65,7 +64,7 @@ public class AccountSshKeyDAO extends AccountOwnedEntityDAO<AccountSshKey> {
} else {
// admin keys are always installed on a node
// never install key for non-admin
key.setInstallSshKey(owner.admin() && thisNetwork.getInstallType() == AnsibleInstallType.node);
key.setInstallSshKey(owner.admin() && thisNetwork.node());
}

final String hash = sha256_hex(key.getSshPublicKey());


+ 1
- 1
bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java Целия файл

@@ -46,7 +46,7 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {
if (errors.hasSuggestedName()) network.setName(errors.getSuggestedName());
}
if (!network.hasNickname()) network.setNickname(network.getName());
final AnsibleInstallType installType = network.hasForkHost() && configuration.isSageLauncher()
final AnsibleInstallType installType = network.hasForkHost() && network.getLaunchType() == LaunchType.fork_sage && configuration.isSageLauncher()
? AnsibleInstallType.sage
: AnsibleInstallType.node;
network.setInstallType(installType);


+ 1
- 1
bubble-server/src/main/java/bubble/main/rekey/RekeyReaderMain.java Целия файл

@@ -57,7 +57,7 @@ public class RekeyReaderMain extends BaseMain<RekeyOptions> {
}

protected Iterator<Identifiable> getEntityProducer(BubbleConfiguration fromConfig, AtomicReference<Exception> error) {
return new FullEntityIterator(fromConfig, null, error);
return new FullEntityIterator(fromConfig, null, null, null, error);
}

}

+ 6
- 1
bubble-server/src/main/java/bubble/model/bill/AccountPlan.java Целия файл

@@ -10,6 +10,7 @@ import bubble.model.account.HasNetwork;
import bubble.model.cloud.BubbleDomain;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.CloudService;
import bubble.model.cloud.LaunchType;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
@@ -46,7 +47,7 @@ public class AccountPlan extends IdentifiableBase implements HasNetwork {
public static final String[] UPDATE_FIELDS = {"description", "paymentMethod", "paymentMethodObject"};

public static final String[] CREATE_FIELDS = ArrayUtil.append(UPDATE_FIELDS,
"name", "forkHost", "locale", "timezone", "domain", "network",
"name", "launchType", "forkHost", "locale", "timezone", "domain", "network",
"sshKey", "syncAccount", "launchLock", "sendErrors", "sendMetrics", "plan", "footprint");

@SuppressWarnings("unused")
@@ -159,6 +160,9 @@ public class AccountPlan extends IdentifiableBase implements HasNetwork {
@JsonIgnore @Transient @Getter @Setter private transient Account accountObject = null;
public boolean hasAccountObject () { return account != null; }

@Transient @Getter @Setter private transient LaunchType launchType = null;
public boolean hasLaunchType () { return launchType != null; }

@Transient @Getter @Setter private transient String forkHost = null;
public boolean hasForkHost () { return !empty(forkHost); }

@@ -195,6 +199,7 @@ public class AccountPlan extends IdentifiableBase implements HasNetwork {
.setFootprint(getFootprint())
.setComputeSizeType(plan.getComputeSizeType())
.setStorage(storage.getUuid())
.setLaunchType(hasForkHost() && hasLaunchType() ? getLaunchType() : LaunchType.node)
.setForkHost(hasForkHost() ? getForkHost() : null);
}



+ 10
- 2
bubble-server/src/main/java/bubble/model/cloud/BubbleNetwork.java Целия файл

@@ -136,6 +136,10 @@ public class BubbleNetwork extends IdentifiableBase implements HasNetwork, HasBu
@ECIndex @Column(nullable=false, updatable=false, length=60) @ECField(index=70)
@Enumerated(EnumType.STRING)
@Getter @Setter private AnsibleInstallType installType;
public boolean sage() { return installType == AnsibleInstallType.sage; }
public boolean notSage() { return !sage(); }
public boolean node() { return installType == AnsibleInstallType.node; }
public boolean notNode() { return !node(); }

@ECSearchable @ECField(index=80)
@ECForeignKey(entity=AccountSshKey.class)
@@ -146,6 +150,7 @@ public class BubbleNetwork extends IdentifiableBase implements HasNetwork, HasBu
@ECSearchable @ECField(index=90)
@ECIndex @Column(nullable=false, updatable=false, length=20)
@Enumerated(EnumType.STRING) @Getter @Setter private ComputeNodeSizeType computeSizeType;
public boolean local() { return computeSizeType == ComputeNodeSizeType.local; }

@ECSearchable @ECField(index=100)
@ECForeignKey(entity=BubbleFootprint.class)
@@ -202,8 +207,11 @@ public class BubbleNetwork extends IdentifiableBase implements HasNetwork, HasBu
public boolean hasForkHost () { return !empty(forkHost); }
public boolean fork() { return hasForkHost(); }

@ECSearchable @ECField(index=190)
@Column(length=20)
@ECField(index=190) @Column(length=20, updatable=false)
@Enumerated(EnumType.STRING) @Getter @Setter private LaunchType launchType = null;
public boolean hasLaunchType () { return launchType != null; }

@ECSearchable @ECField(index=200) @Column(length=20)
@Enumerated(EnumType.STRING) @Getter @Setter private BubbleNetworkState state = created;

public String hostFromFqdn(String fqdn) {


+ 2
- 0
bubble-server/src/main/java/bubble/model/cloud/BubbleNode.java Целия файл

@@ -131,6 +131,8 @@ public class BubbleNode extends IdentifiableBase implements HasNetwork, HasBubbl
@ECIndex @Column(nullable=false, updatable=false, length=60)
@Enumerated(EnumType.STRING)
@Getter @Setter private AnsibleInstallType installType;
public boolean sage() { return installType == AnsibleInstallType.sage; }
public boolean node() { return installType == AnsibleInstallType.node; }

@ECSearchable @ECField(index=50)
@ECForeignKey(entity=BubbleNode.class, cascade=false)


+ 17
- 0
bubble-server/src/main/java/bubble/model/cloud/LaunchType.java Целия файл

@@ -0,0 +1,17 @@
/**
* Copyright (c) 2020 Bubble, Inc. All rights reserved.
* For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
*/
package bubble.model.cloud;

import com.fasterxml.jackson.annotation.JsonCreator;

import static bubble.ApiConstants.enumFromString;

public enum LaunchType {

node, fork_node, fork_sage;

@JsonCreator public static LaunchType fromString(String v) { return enumFromString(LaunchType.class, v); }

}

+ 3
- 0
bubble-server/src/main/java/bubble/notify/NewNodeNotification.java Целия файл

@@ -8,6 +8,7 @@ import bubble.cloud.CloudAndRegion;
import bubble.model.account.AccountContact;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.LaunchType;
import bubble.model.cloud.NetLocation;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
@@ -51,6 +52,8 @@ public class NewNodeNotification {
@Getter @Setter private Boolean fork;
public boolean fork() { return fork != null && fork; }

@Getter @Setter private LaunchType launchType;

@Getter @Setter private String restoreKey;
public boolean hasRestoreKey () { return !empty(restoreKey); }



+ 2
- 3
bubble-server/src/main/java/bubble/notify/NotificationHandler_sync_account.java Целия файл

@@ -7,7 +7,6 @@ package bubble.notify;
import bubble.dao.account.AccountDAO;
import bubble.dao.account.AccountPolicyDAO;
import bubble.dao.cloud.BubbleNodeDAO;
import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.notify.ReceivedNotification;
import bubble.service.account.SyncAccountNotification;
import lombok.extern.slf4j.Slf4j;
@@ -49,7 +48,7 @@ public class NotificationHandler_sync_account extends ReceivedNotificationHandle
localAccount.getHashedPassword().setHashedPassword(incomingHashedPassword);
// if we are a node, set skipSync so we don't get caught in an infinite loop
// (the node would notify the sage, which would notify the node, ad infinitum)
localAccount.setSkipSync(configuration.getThisNetwork().getInstallType() == AnsibleInstallType.node);
localAccount.setSkipSync(configuration.getThisNetwork().node());
// update password, if we are a sage, this will notify all networks of password change
accountDAO.update(localAccount);
}
@@ -63,7 +62,7 @@ public class NotificationHandler_sync_account extends ReceivedNotificationHandle
}
localPolicy.update(incomingPolicy);
localPolicy.setAccountContactsJson(incomingPolicy.getAccountContactsJson());
localPolicy.setSkipSync(configuration.getThisNetwork().getInstallType() == AnsibleInstallType.node);
localPolicy.setSkipSync(configuration.getThisNetwork().node());
accountPolicyDAO.update(localPolicy);
}
}


+ 3
- 2
bubble-server/src/main/java/bubble/resources/account/AuthResource.java Целия файл

@@ -432,8 +432,9 @@ public class AuthResource {
final BubbleNetwork thisNetwork = configuration.getThisNetwork();
if (thisNetwork != null
&& thisNetwork.syncAccount()
&& thisNetwork.getInstallType() == AnsibleInstallType.node
&& configuration.hasSageNode()) {
&& thisNetwork.node()
&& configuration.hasSageNode()
&& !configuration.isSelfSage()) {
// check if session is valid on sage
@Cleanup final BubbleNodeClient sageClient = configuration.getSageNode().getApiQuickClient(configuration);
try {


+ 4
- 3
bubble-server/src/main/java/bubble/server/BubbleConfiguration.java Целия файл

@@ -143,12 +143,13 @@ public class BubbleConfiguration extends PgRestServerConfiguration
return selfNode != null && selfNode.selfSage();
}
@JsonIgnore @Transient public boolean isSageLauncher() {
return isSelfSage() || !hasSageNode();
final BubbleNetwork thisNetwork = getThisNetwork();
return (isSelfSage() || !hasSageNode()) && thisNetwork.sage();
}

@JsonIgnore @Transient public boolean isSage() {
final BubbleNetwork thisNetwork = getThisNetwork();
return thisNetwork != null && thisNetwork.getInstallType() == AnsibleInstallType.sage;
return thisNetwork != null && thisNetwork.sage();
}

@JsonIgnore @Transient public synchronized BubbleNetwork getThisNetwork () {
@@ -356,7 +357,7 @@ public class BubbleConfiguration extends PgRestServerConfiguration
{TAG_ALLOW_REGISTRATION, thisNetwork == null ? null : thisNetwork.getBooleanTag(TAG_ALLOW_REGISTRATION, false)},
{TAG_NETWORK_UUID, thisNetwork == null ? null : thisNetwork.getUuid()},
{TAG_SAGE_LAUNCHER, thisNetwork == null || isSageLauncher()},
{TAG_BUBBLE_NODE, isSageLauncher() || thisNetwork == null ? null : thisNetwork.getInstallType() == AnsibleInstallType.node},
{TAG_BUBBLE_NODE, isSageLauncher() || thisNetwork == null ? null : thisNetwork.node()},
{TAG_PAYMENTS_ENABLED, cloudDAO.paymentsEnabled()},
{TAG_PROMO_CODE_POLICY, getPromoCodePolicy().name()},
{TAG_REQUIRE_SEND_METRICS, requireSendMetrics()},


+ 2
- 3
bubble-server/src/main/java/bubble/server/listener/NodeInitializerListener.java Целия файл

@@ -7,14 +7,13 @@ package bubble.server.listener;
import bubble.dao.account.AccountDAO;
import bubble.dao.cloud.CloudServiceDAO;
import bubble.model.account.Account;
import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.CloudService;
import bubble.server.BubbleConfiguration;
import bubble.service.boot.SelfNodeService;
import bubble.service.device.DeviceService;
import bubble.service.cloud.NetworkMonitorService;
import bubble.service.device.DeviceService;
import bubble.service.device.StandardFlexRouterService;
import bubble.service.stream.AppDataCleaner;
import bubble.service.stream.AppPrimerService;
@@ -111,7 +110,7 @@ public class NodeInitializerListener extends RestServerLifecycleListenerBase<Bub
// and start AppDataCleaner
if (thisNode != null) {
final BubbleNetwork thisNetwork = c.getThisNetwork();
if (thisNetwork != null && thisNetwork.getInstallType() == AnsibleInstallType.node) {
if (thisNetwork != null && thisNetwork.node()) {
c.getBean(AppPrimerService.class).primeApps();
c.getBean(StandardFlexRouterService.class).start();
c.getBean(DeviceService.class).initDeviceSecurityLevels();


+ 1
- 2
bubble-server/src/main/java/bubble/service/account/MitmControlService.java Целия файл

@@ -4,7 +4,6 @@
*/
package bubble.service.account;

import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.service.boot.SelfNodeService;
import lombok.extern.slf4j.Slf4j;
@@ -83,7 +82,7 @@ public class MitmControlService {

public void checkMitmInstalled() {
final BubbleNetwork thisNetwork = selfNodeService.getThisNetwork();
if (thisNetwork == null || thisNetwork.getInstallType() != AnsibleInstallType.node) {
if (thisNetwork == null || thisNetwork.notNode()) {
throw invalidEx("err.mitm.notInstalled");
}
}


+ 7
- 6
bubble-server/src/main/java/bubble/service/boot/StandardSelfNodeService.java Целия файл

@@ -148,8 +148,10 @@ public class StandardSelfNodeService implements SelfNodeService {

// start hello sage and spare devices services, if we have a sage that is not ourselves
if (!c.isSage()) {
log.info("onStart: starting SageHelloService");
c.getBean(SageHelloService.class).start();
if (thisNode.node() && !c.isSelfSage()) {
log.info("onStart: starting SageHelloService");
c.getBean(SageHelloService.class).start();
}

log.info("onStart: building spare devices for all account that are not root account");
background(() -> {
@@ -165,7 +167,7 @@ public class StandardSelfNodeService implements SelfNodeService {
}

// start RefundService if payments are enabled and this is a SageLauncher
if (c.paymentsEnabled() && c.isSageLauncher()) {
if (c.paymentsEnabled() && c.isSageLauncher() && thisNode.sage()) {
log.info("onStart: starting BillingService and RefundService");
c.getBean(BillingService.class).start();
c.getBean(StandardRefundService.class).start();
@@ -435,7 +437,7 @@ public class StandardSelfNodeService implements SelfNodeService {
@Override public BubblePlan getThisPlan() {
final BubbleNetwork network = safeGetThisNetwork();
if (network == null) return null;
if (network.getInstallType() != AnsibleInstallType.node) return null;
if (network.notNode()) return null;
final AccountPlan accountPlan = accountPlanDAO.findByNetwork(network.getUuid());
if (accountPlan == null) return null;
return planDAO.findByUuid(accountPlan.getPlan());
@@ -451,8 +453,7 @@ public class StandardSelfNodeService implements SelfNodeService {
return ttl < 0 ? Optional.empty() : Optional.of(now() + ttl * 1000);
}

@Override
public void setLogFlag(final boolean logFlag, @NonNull final Optional<Integer> ttlInSeconds) {
@Override public void setLogFlag(final boolean logFlag, @NonNull final Optional<Integer> ttlInSeconds) {
if (logFlag) {
getNodeConfig().set_plaintext(REDIS_LOG_FLAG_KEY, "true", EX,
ttlInSeconds.orElse(isSelfSage() ? TTL_LOG_FLAG_SAGE : TTL_LOG_FLAG_NODE));


+ 3
- 1
bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java Целия файл

@@ -16,6 +16,7 @@ import bubble.model.bill.BubblePlanApp;
import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.LaunchType;
import bubble.server.BubbleConfiguration;
import bubble.service.dbfilter.DatabaseFilterService;
import com.github.jknack.handlebars.Handlebars;
@@ -61,6 +62,7 @@ public class AnsiblePrepService {
ComputeServiceDriver computeDriver,
ValidationResult errors,
boolean fork,
LaunchType launchType,
String restoreKey) throws IOException {
final BubbleConfiguration c = configuration;

@@ -113,7 +115,7 @@ public class AnsiblePrepService {
}

// Copy database with new encryption key
final String key = dbFilter.copyDatabase(fork, network, node, account, planApps, new File(bubbleFilesDir, "bubble.sql.gz"));
final String key = dbFilter.copyDatabase(fork, launchType, network, node, account, planApps, new File(bubbleFilesDir, "bubble.sql.gz"));
ctx.put("dbEncryptionKey", key);

// if this is a fork, and current server is local, then sage will be self


+ 1
- 2
bubble-server/src/main/java/bubble/service/cloud/NodeLaunchMonitor.java Целия файл

@@ -4,7 +4,6 @@
*/
package bubble.service.cloud;

import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.notify.NewNodeNotification;
import bubble.server.BubbleConfiguration;
@@ -80,7 +79,7 @@ public class NodeLaunchMonitor extends SimpleDaemon {
if (thisNetwork == null) {
die("register: thisNetwork is null");

} else if (configuration.isSageLauncher() || thisNetwork.getInstallType() == AnsibleInstallType.sage) {
} else if (thisNetwork.sage()) {
if (log.isInfoEnabled()) log.info("register: first registration, starting launch monitor");
start();



+ 4
- 3
bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java Целия файл

@@ -352,7 +352,7 @@ public class StandardNetworkService implements NetworkService {
if (!setupOk) return launchFailureCanRetry(node, "newNode: error setting up, all retries failed for node: "+node.getUuid());

// wait for node to be ready
if (node.getInstallType() == AnsibleInstallType.node) {
if (node.node()) {
final long readyStart = now();
boolean ready = false;
Exception lastEx = null;
@@ -479,7 +479,7 @@ public class StandardNetworkService implements NetworkService {
progressMeter.write(METER_TICK_PREPARING_ROLES);
final Map<String, Object> ctx = ansiblePrep.prepAnsible(
automation, bubbleFilesDir, account, network, node, computeDriver,
errors, nn.fork(), nn.getRestoreKey());
errors, nn.fork(), nn.getLaunchType(), nn.getRestoreKey());
if (errors.isInvalid()) {
progressMeter.error(METER_ERROR_ROLE_VALIDATION_ERRORS);
fatalLaunchFailure(node, new MultiViolationException(errors.getViolationBeans()));
@@ -519,7 +519,7 @@ public class StandardNetworkService implements NetworkService {
writeFile(bubbleFilesDir, null, SAGE_KEY_JSON, json(BubbleNodeKey.sageMask(sageKey)));

// write packer keys if launching sage
if (network.getInstallType() == AnsibleInstallType.sage) {
if (network.sage()) {
final File packerPubKeyFile = new File(bubbleFilesDir, PACKER_KEY_NAME+".pub");
copyFile(packerService.getPackerPublicKey(), packerPubKeyFile);

@@ -726,6 +726,7 @@ public class StandardNetworkService implements NetworkService {

final NewNodeNotification newNodeRequest = new NewNodeNotification()
.setFork(network.fork())
.setLaunchType(network.getLaunchType())
.setNodeHost(network)
.setNetLocation(netLocation)
.setLock(lock);


+ 4
- 2
bubble-server/src/main/java/bubble/service/dbfilter/DatabaseFilterService.java Целия файл

@@ -12,6 +12,7 @@ import bubble.model.account.Account;
import bubble.model.bill.BubblePlanApp;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.LaunchType;
import bubble.server.BubbleConfiguration;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
@@ -53,11 +54,12 @@ public class DatabaseFilterService {

public static final String ENV_OLD_DB_KEY = "OLD_DB_KEY";
public static final String ENV_NEW_DB_KEY = "NEW_DB_KEY";
public static final String[] FLYWAY_DUMP_OPTIONS = {"--table=flyway_schema_history", "--data-only"};
public static final String[] FLYWAY_DUMP_OPTIONS = {"--table="+getFlywayTableName(), "--data-only"};

@Autowired private BubbleConfiguration configuration;

public String copyDatabase(boolean fork,
LaunchType launchType,
BubbleNetwork network,
BubbleNode node,
Account account,
@@ -112,7 +114,7 @@ public class DatabaseFilterService {
@Override public RekeyOptions getOptions() { return readerOptions; }
@Override protected Iterator<Identifiable> getEntityProducer(BubbleConfiguration fromConfig, AtomicReference<Exception> error) {
return fork
? new FullEntityIterator(configuration, network, readerError)
? new FullEntityIterator(configuration, account, network, launchType, readerError)
: new FilteredEntityIterator(configuration, account, network, node, planApps, readerError);
}
}.runInBackground("RekeyReaderMain.reader", readerError::set);


+ 17
- 0
bubble-server/src/main/java/bubble/service/dbfilter/FullEntityIterator.java Целия файл

@@ -4,32 +4,49 @@
*/
package bubble.service.dbfilter;

import bubble.dao.device.DeviceDAO;
import bubble.model.account.Account;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.LaunchType;
import bubble.server.BubbleConfiguration;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicReference;

import static bubble.model.device.Device.newUninitializedDevice;
import static org.cobbzilla.wizard.dao.AbstractCRUDDAO.ORDER_CTIME_ASC;

@Slf4j
public class FullEntityIterator extends EntityIterator {

private final BubbleConfiguration config;
private final Account account;
private final BubbleNetwork network;
private final LaunchType launchType;

public FullEntityIterator (BubbleConfiguration config,
Account account,
BubbleNetwork network,
LaunchType launchType,
AtomicReference<Exception> error) {
super(error);
this.config = config;
this.network = network;
this.account = account;
this.launchType = launchType;
}

protected void iterate() {
config.getEntityClasses()
.forEach(c -> addEntities(true, c, config.getDaoForEntityClass(c).findAll(ORDER_CTIME_ASC),
network, null, null));
if (account != null && launchType != null && launchType == LaunchType.fork_node) {
// add an initial device so that algo starts properly the first time
// name and totp key will be overwritten when the device is initialized for use
log.info("iterate: creating a single dummy device for algo to start properly");
final var initDevice = newUninitializedDevice(network.getUuid(), account.getUuid());
add(config.getBean(DeviceDAO.class).create(initDevice));
}
log.info("iterate: completed");
}



+ 1
- 2
bubble-server/src/main/java/bubble/service/stream/StandardAppPrimerService.java Целия файл

@@ -9,7 +9,6 @@ import bubble.dao.app.*;
import bubble.dao.device.DeviceDAO;
import bubble.model.account.Account;
import bubble.model.app.*;
import bubble.model.cloud.AnsibleInstallType;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.device.Device;
import bubble.rule.AppRuleDriver;
@@ -54,7 +53,7 @@ public class StandardAppPrimerService implements AppPrimerService {
log.info("initPrimingEnabled: thisNetwork is null, not priming");
return false;
}
if (thisNetwork.getInstallType() != AnsibleInstallType.node) {
if (thisNetwork.notNode()) {
log.info("initPrimingEnabled: thisNetwork is not a node, not priming");
return false;
}


+ 1
- 1
bubble-server/src/main/resources/META-INF/bubble/bubble.properties Целия файл

@@ -1 +1 @@
bubble.version=Adventure 1.2.1
bubble.version=Adventure 1.2.2

+ 0
- 1486
bubble-server/src/main/resources/apps.json
Файловите разлики са ограничени, защото са твърде много
Целия файл


+ 1
- 0
bubble-server/src/main/resources/db/migration/V2020091801__add_network_launch_type.sql Целия файл

@@ -0,0 +1 @@
ALTER TABLE bubble_network ADD COLUMN launch_type VARCHAR(200);

+ 1
- 1
bubble-server/src/main/resources/messages

@@ -1 +1 @@
Subproject commit 61fc9667c4c66c0bcbbb8eb4d128e8ab58f50869
Subproject commit 9d1ecac6514696721effe012e9c726896c368ebe

+ 2
- 3
bubble-server/src/main/resources/packer/roles/mitmproxy/files/bubble_api.py Целия файл

@@ -25,7 +25,6 @@ from bubble_config import bubble_port, debug_capture_fqdn, \
from mitmproxy import http
from mitmproxy.net.http import headers as nheaders
from mitmproxy.proxy.protocol.async_stream_body import AsyncStreamBody
from mitmproxy.proxy.protocol.request_capture import RequestCapture

bubble_log = logging.getLogger(__name__)

@@ -401,7 +400,7 @@ def is_bubble_health_check(path):


def is_sage_request(ip, fqdns):
return (ip == bubble_sage_ip4 or ip == bubble_sage_ip6) and bubble_sage_host in fqdns
return fqdns is not None and (ip == bubble_sage_ip4 or ip == bubble_sage_ip6) and bubble_sage_host in fqdns


def is_not_from_vpn(client_addr):
@@ -416,7 +415,7 @@ def is_flex_domain(client_addr, server_addr, fqdns):
return False
fqdn = fqdns[0]

if fqdn == bubble_host or fqdn == bubble_host_alias or fqdn == bubble_sage_host:
if fqdn == bubble_host or fqdn == bubble_host_alias or (bubble_sage_host is not None and fqdn == bubble_sage_host):
if bubble_log.isEnabledFor(DEBUG):
bubble_log.debug('is_flex_domain: (early) returning False for: '+fqdn)
return False


+ 1
- 1
bubble-web

@@ -1 +1 @@
Subproject commit 66d46695a64ff58934560c4b35aa43a0ab32fbe2
Subproject commit 37dd89bd78949a63c68a64596b4e1c105809a577

+ 1
- 1
utils/cobbzilla-utils

@@ -1 +1 @@
Subproject commit dfafe62c7eb3413cf1210e40e551094458f4d9d0
Subproject commit fab2bdafe756fc53ff80b58171fb9000846bf0ef

Зареждане…
Отказ
Запис