@@ -10,11 +10,13 @@ | |||||
<parent> | <parent> | ||||
<groupId>bubble</groupId> | <groupId>bubble</groupId> | ||||
<artifactId>bubble</artifactId> | <artifactId>bubble</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<!-- @@BUBBLE_VERSION@@ this comment must remain above the version tag so that _set_version can update it --> | |||||
<version>1.5.1</version> | |||||
</parent> | </parent> | ||||
<artifactId>bubble-server</artifactId> | <artifactId>bubble-server</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<!-- @@BUBBLE_VERSION@@ this comment must remain above the version tag so that _set_version can update it --> | |||||
<version>1.5.1</version> | |||||
<repositories> | <repositories> | ||||
<repository> | <repository> | ||||
@@ -57,7 +59,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>org.cobbzilla</groupId> | <groupId>org.cobbzilla</groupId> | ||||
<artifactId>cobbzilla-utils</artifactId> | <artifactId>cobbzilla-utils</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
<exclusions> | <exclusions> | ||||
<!-- we imported poi above ourselves, with our own exclusions --> | <!-- we imported poi above ourselves, with our own exclusions --> | ||||
<exclusion> | <exclusion> | ||||
@@ -115,7 +117,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>org.cobbzilla</groupId> | <groupId>org.cobbzilla</groupId> | ||||
<artifactId>wizard-server</artifactId> | <artifactId>wizard-server</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
<exclusions> | <exclusions> | ||||
<exclusion> | <exclusion> | ||||
<groupId>org.eclipse.jetty</groupId> | <groupId>org.eclipse.jetty</groupId> | ||||
@@ -144,7 +146,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>bubble</groupId> | <groupId>bubble</groupId> | ||||
<artifactId>abp-parser</artifactId> | <artifactId>abp-parser</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
</dependency> | </dependency> | ||||
<!-- RDBMS persistence --> | <!-- RDBMS persistence --> | ||||
@@ -172,7 +174,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>org.cobbzilla</groupId> | <groupId>org.cobbzilla</groupId> | ||||
<artifactId>templated-mail-sender</artifactId> | <artifactId>templated-mail-sender</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
</dependency> | </dependency> | ||||
<dependency> | <dependency> | ||||
@@ -375,7 +377,7 @@ | |||||
<dependency> | <dependency> | ||||
<groupId>org.cobbzilla</groupId> | <groupId>org.cobbzilla</groupId> | ||||
<artifactId>wizard-server-test</artifactId> | <artifactId>wizard-server-test</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
<scope>test</scope> | <scope>test</scope> | ||||
</dependency> | </dependency> | ||||
</dependencies> | </dependencies> | ||||
@@ -687,7 +689,7 @@ The exclusions below were generated with: | |||||
<phase>package</phase> | <phase>package</phase> | ||||
<goals><goal>shade</goal></goals> | <goals><goal>shade</goal></goals> | ||||
<configuration> | <configuration> | ||||
<outputFile>${project.basedir}/target/bubble-server-1.0.0-SNAPSHOT-full.jar</outputFile> | |||||
<outputFile>${project.basedir}/target/bubble-server-${project.version}-full.jar</outputFile> | |||||
<transformers> | <transformers> | ||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> | ||||
<mainClass>bubble.server.BubbleServer</mainClass> | <mainClass>bubble.server.BubbleServer</mainClass> | ||||
@@ -197,11 +197,6 @@ public class NoopCloud implements | |||||
return null; | return null; | ||||
} | } | ||||
@Override public Collection<DnsRecord> setNetwork(BubbleNetwork network) { | |||||
if (log.isDebugEnabled()) log.debug("setNetwork(network=" + network + ")"); | |||||
return null; | |||||
} | |||||
@Override public Collection<DnsRecord> setNode(BubbleNode node) { | @Override public Collection<DnsRecord> setNode(BubbleNode node) { | ||||
if (log.isDebugEnabled()) log.debug("setNode(node=" + node + ")"); | if (log.isDebugEnabled()) log.debug("setNode(node=" + node + ")"); | ||||
return null; | return null; | ||||
@@ -10,6 +10,7 @@ import bubble.cloud.CloudServiceType; | |||||
import bubble.model.cloud.AnsibleInstallType; | import bubble.model.cloud.AnsibleInstallType; | ||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import bubble.model.cloud.RegionalServiceDriver; | import bubble.model.cloud.RegionalServiceDriver; | ||||
import bubble.service.packer.PackerBuild; | |||||
import org.cobbzilla.util.system.CommandResult; | import org.cobbzilla.util.system.CommandResult; | ||||
import java.util.List; | import java.util.List; | ||||
@@ -44,4 +45,25 @@ public interface ComputeServiceDriver extends CloudServiceDriver, RegionalServic | |||||
default int getPackerParallelBuilds() { return 1; } | default int getPackerParallelBuilds() { return 1; } | ||||
default boolean supportsPacker(AnsibleInstallType installType) { return true; } | |||||
default CloudRegion[] getRegions(PackerBuild packerBuild) { | |||||
final String[] parts = packerBuild.getArtifact_id().split(":"); | |||||
final String[] regionNames = parts[0].split(","); | |||||
final CloudRegion[] regions = new CloudRegion[regionNames.length]; | |||||
for (int i=0; i<regionNames.length; i++) { | |||||
regions[i] = new CloudRegion().setInternalName(regionNames[i]); | |||||
} | |||||
return regions; | |||||
} | |||||
default String getPackerImageId(String name, PackerBuild packerBuild) { | |||||
final String[] parts = packerBuild.getArtifact_id().split(":"); | |||||
return parts[1]; | |||||
} | |||||
default boolean supportsDns() { return true; } | |||||
default int getSshPort(BubbleNode node) { return 1202; } | |||||
} | } |
@@ -2,13 +2,18 @@ package bubble.cloud.compute.docker; | |||||
import bubble.cloud.CloudRegion; | import bubble.cloud.CloudRegion; | ||||
import bubble.cloud.compute.*; | import bubble.cloud.compute.*; | ||||
import bubble.model.cloud.AnsibleInstallType; | |||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import bubble.model.cloud.BubbleNodeState; | import bubble.model.cloud.BubbleNodeState; | ||||
import bubble.model.cloud.CloudCredentials; | import bubble.model.cloud.CloudCredentials; | ||||
import bubble.service.packer.PackerBuild; | |||||
import com.github.dockerjava.api.DockerClient; | import com.github.dockerjava.api.DockerClient; | ||||
import com.github.dockerjava.api.command.CreateContainerCmd; | |||||
import com.github.dockerjava.api.command.CreateContainerResponse; | import com.github.dockerjava.api.command.CreateContainerResponse; | ||||
import com.github.dockerjava.api.command.InspectContainerResponse; | import com.github.dockerjava.api.command.InspectContainerResponse; | ||||
import com.github.dockerjava.api.model.Capability; | |||||
import com.github.dockerjava.api.model.Container; | import com.github.dockerjava.api.model.Container; | ||||
import com.github.dockerjava.api.model.HostConfig; | |||||
import com.github.dockerjava.api.model.Image; | import com.github.dockerjava.api.model.Image; | ||||
import com.github.dockerjava.core.DefaultDockerClientConfig; | import com.github.dockerjava.core.DefaultDockerClientConfig; | ||||
import com.github.dockerjava.core.DockerClientConfig; | import com.github.dockerjava.core.DockerClientConfig; | ||||
@@ -16,6 +21,7 @@ import com.github.dockerjava.core.DockerClientImpl; | |||||
import com.github.dockerjava.transport.DockerHttpClient; | import com.github.dockerjava.transport.DockerHttpClient; | ||||
import com.github.dockerjava.zerodep.ZerodepDockerHttpClient; | import com.github.dockerjava.zerodep.ZerodepDockerHttpClient; | ||||
import edu.emory.mathcs.backport.java.util.Arrays; | import edu.emory.mathcs.backport.java.util.Arrays; | ||||
import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap; | |||||
import lombok.Getter; | import lombok.Getter; | ||||
import lombok.extern.slf4j.Slf4j; | import lombok.extern.slf4j.Slf4j; | ||||
import org.cobbzilla.util.collection.MapBuilder; | import org.cobbzilla.util.collection.MapBuilder; | ||||
@@ -23,20 +29,26 @@ import org.cobbzilla.util.collection.MapBuilder; | |||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.ArrayList; | import java.util.ArrayList; | ||||
import java.util.List; | import java.util.List; | ||||
import java.util.Map; | |||||
import java.util.function.Predicate; | |||||
import static bubble.service.packer.PackerJob.PACKER_IMAGE_PREFIX; | import static bubble.service.packer.PackerJob.PACKER_IMAGE_PREFIX; | ||||
import static java.lang.Boolean.parseBoolean; | import static java.lang.Boolean.parseBoolean; | ||||
import static java.util.concurrent.TimeUnit.SECONDS; | import static java.util.concurrent.TimeUnit.SECONDS; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.*; | import static org.cobbzilla.util.daemon.ZillaRuntime.*; | ||||
import static org.cobbzilla.util.json.JsonUtil.json; | import static org.cobbzilla.util.json.JsonUtil.json; | ||||
import static org.cobbzilla.util.system.OsType.CURRENT_OS; | |||||
import static org.cobbzilla.util.system.OsType.linux; | |||||
import static org.cobbzilla.util.system.Sleep.sleep; | import static org.cobbzilla.util.system.Sleep.sleep; | ||||
@Slf4j | @Slf4j | ||||
public class DockerComputeDriver extends ComputeServiceDriverBase { | public class DockerComputeDriver extends ComputeServiceDriverBase { | ||||
public static final List<CloudRegion> CLOUD_REGIONS = Arrays.asList(new CloudRegion[]{ | |||||
public static final CloudRegion[] CLOUD_REGIONS_ARRAY = new CloudRegion[]{ | |||||
new CloudRegion().setName("local").setInternalName("local") | new CloudRegion().setName("local").setInternalName("local") | ||||
}); | |||||
}; | |||||
public static final List<CloudRegion> CLOUD_REGIONS = Arrays.asList(CLOUD_REGIONS_ARRAY); | |||||
public static final List<ComputeNodeSize> CLOUD_SIZES = Arrays.asList(new ComputeNodeSize[]{ | public static final List<ComputeNodeSize> CLOUD_SIZES = Arrays.asList(new ComputeNodeSize[]{ | ||||
new ComputeNodeSize().setName("local").setInternalName("local").setType(ComputeNodeSizeType.local) | new ComputeNodeSize().setName("local").setInternalName("local").setType(ComputeNodeSizeType.local) | ||||
}); | }); | ||||
@@ -55,6 +67,24 @@ public class DockerComputeDriver extends ComputeServiceDriverBase { | |||||
@Getter private final List<ComputeNodeSize> cloudSizes = CLOUD_SIZES; | @Getter private final List<ComputeNodeSize> cloudSizes = CLOUD_SIZES; | ||||
@Getter private final List<OsImage> cloudOsImages = CLOUD_OS_IMAGES; | @Getter private final List<OsImage> cloudOsImages = CLOUD_OS_IMAGES; | ||||
@Override public boolean supportsPacker(AnsibleInstallType installType) { | |||||
boolean supported = installType == AnsibleInstallType.sage || CURRENT_OS == linux; | |||||
if (!supported) log.warn("supportsPacker: installType "+installType+" not supported (no images will be created) for platform: "+CURRENT_OS); | |||||
return supported; | |||||
} | |||||
@Override public boolean supportsDns() { return false; } | |||||
@Override public CloudRegion[] getRegions(PackerBuild packerBuild) { return CLOUD_REGIONS_ARRAY; } | |||||
@Override public String getPackerImageId(String name, PackerBuild packerBuild) { return name; } | |||||
private final Map<String, Map<Integer, Integer>> portMappings = new ConcurrentHashMap(); | |||||
@Override public int getSshPort(BubbleNode node) { | |||||
return portMappings.get(node.getUuid()).get(1202); | |||||
} | |||||
@Getter(lazy=true) private final DockerClient dockerClient = initDockerClient(); | @Getter(lazy=true) private final DockerClient dockerClient = initDockerClient(); | ||||
private DockerClient initDockerClient() { | private DockerClient initDockerClient() { | ||||
CloudCredentials creds = getCredentials(); | CloudCredentials creds = getCredentials(); | ||||
@@ -88,20 +118,31 @@ public class DockerComputeDriver extends ComputeServiceDriverBase { | |||||
final PackerImage packerImage = getOrCreatePackerImage(node); | final PackerImage packerImage = getOrCreatePackerImage(node); | ||||
final CreateContainerResponse ccr = dc.createContainerCmd(packerImage.getId()) | |||||
final CreateContainerCmd ccr = dc.createContainerCmd(packerImage.getId()) | |||||
.withLabels(MapBuilder.build(new String[][] { | .withLabels(MapBuilder.build(new String[][] { | ||||
{LABEL_CLOUD, cloud.getUuid()}, | {LABEL_CLOUD, cloud.getUuid()}, | ||||
{LABEL_NODE, node.getUuid()} | {LABEL_NODE, node.getUuid()} | ||||
})) | })) | ||||
.exec(); | |||||
.withHostConfig(HostConfig.newHostConfig() | |||||
.withCapAdd(Capability.NET_ADMIN) | |||||
.withCapAdd(Capability.SYS_ADMIN)); | |||||
final CreateContainerResponse response = ccr.exec(); | |||||
final long start = now(); | final long start = now(); | ||||
while (listNodes().stream().noneMatch(n -> n.isRunning() && n.getUuid().equals(node.getUuid()))) { | |||||
final Predicate<? super BubbleNode> nodeFilter = filterForNode(node); | |||||
while (listNodes().stream().noneMatch(nodeFilter)) { | |||||
if (now() - start > START_TIMEOUT) { | if (now() - start > START_TIMEOUT) { | ||||
return die("start("+node.id()+"): timeout"); | return die("start("+node.id()+"): timeout"); | ||||
} | } | ||||
sleep(SECONDS.toMillis(5), "waiting for docker container to be running"); | sleep(SECONDS.toMillis(5), "waiting for docker container to be running"); | ||||
} | } | ||||
return node; | |||||
final String containerId = lookupContainer(node); | |||||
final InspectContainerResponse status = dc.inspectContainerCmd(containerId).exec(); | |||||
return node.setIp4("127.0.0.1").setIp6("fd00::1"); | |||||
} | |||||
private Predicate<? super BubbleNode> filterForNode(BubbleNode node) { | |||||
return n -> n.isRunning() && n.getUuid().equals(node.getUuid()); | |||||
} | } | ||||
private String lookupContainer(BubbleNode node) { | private String lookupContainer(BubbleNode node) { | ||||
@@ -23,7 +23,6 @@ import java.util.List; | |||||
import static java.util.concurrent.TimeUnit.MINUTES; | import static java.util.concurrent.TimeUnit.MINUTES; | ||||
import static org.cobbzilla.util.daemon.ZillaRuntime.die; | import static org.cobbzilla.util.daemon.ZillaRuntime.die; | ||||
import static org.cobbzilla.util.network.NetworkUtil.IPv4_ALL_ADDRS; | |||||
public abstract class DnsDriverBase<T> extends CloudServiceDriverBase<T> implements DnsServiceDriver { | public abstract class DnsDriverBase<T> extends CloudServiceDriverBase<T> implements DnsServiceDriver { | ||||
@@ -79,22 +78,6 @@ public abstract class DnsDriverBase<T> extends CloudServiceDriverBase<T> impleme | |||||
return null; | return null; | ||||
} | } | ||||
@Override public Collection<DnsRecord> setNetwork(BubbleNetwork network) { | |||||
final DnsServiceDriver dns = cloud.getDnsDriver(configuration); | |||||
final Collection<DnsRecord> records = new ArrayList<>(); | |||||
if (dns.requireSubnetNS()) { | |||||
final BubbleDomain domain = domainDAO.findByUuid(network.getDomain()); | |||||
for (String ns : dns.resolveNS(domain)) { | |||||
records.add(dns.update((DnsRecord) new DnsRecord() | |||||
.setOption(DnsRecord.OPT_NS_NAME, ns) | |||||
.setType(DnsType.NS) | |||||
.setValue(IPv4_ALL_ADDRS) | |||||
.setFqdn(network.getNetworkDomain()))); | |||||
} | |||||
} | |||||
return records; | |||||
} | |||||
@Override public Collection<DnsRecord> setNode(BubbleNode node) { | @Override public Collection<DnsRecord> setNode(BubbleNode node) { | ||||
final DnsServiceDriver dns = cloud.getDnsDriver(configuration); | final DnsServiceDriver dns = cloud.getDnsDriver(configuration); | ||||
final BubbleNetwork network = networkDAO.findByUuid(node.getNetwork()); | final BubbleNetwork network = networkDAO.findByUuid(node.getNetwork()); | ||||
@@ -7,7 +7,6 @@ package bubble.cloud.dns; | |||||
import bubble.cloud.CloudServiceDriver; | import bubble.cloud.CloudServiceDriver; | ||||
import bubble.cloud.CloudServiceType; | import bubble.cloud.CloudServiceType; | ||||
import bubble.model.cloud.BubbleDomain; | import bubble.model.cloud.BubbleDomain; | ||||
import bubble.model.cloud.BubbleNetwork; | |||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import org.cobbzilla.util.dns.DnsRecord; | import org.cobbzilla.util.dns.DnsRecord; | ||||
import org.cobbzilla.util.dns.DnsRecordBase; | import org.cobbzilla.util.dns.DnsRecordBase; | ||||
@@ -42,7 +41,6 @@ public interface DnsServiceDriver extends CloudServiceDriver { | |||||
Collection<DnsRecord> create(BubbleDomain domain); | Collection<DnsRecord> create(BubbleDomain domain); | ||||
Collection<DnsRecord> setNetwork(BubbleNetwork network); | |||||
Collection<DnsRecord> setNode(BubbleNode node); | Collection<DnsRecord> setNode(BubbleNode node); | ||||
Collection<DnsRecord> deleteNode(BubbleNode node); | Collection<DnsRecord> deleteNode(BubbleNode node); | ||||
@@ -213,5 +211,4 @@ public interface DnsServiceDriver extends CloudServiceDriver { | |||||
return true; | return true; | ||||
} | } | ||||
default boolean requireSubnetNS() { return false; } | |||||
} | } |
@@ -7,7 +7,6 @@ package bubble.cloud.dns.delegate; | |||||
import bubble.cloud.DelegatedCloudServiceDriverBase; | import bubble.cloud.DelegatedCloudServiceDriverBase; | ||||
import bubble.cloud.dns.DnsServiceDriver; | import bubble.cloud.dns.DnsServiceDriver; | ||||
import bubble.model.cloud.BubbleDomain; | import bubble.model.cloud.BubbleDomain; | ||||
import bubble.model.cloud.BubbleNetwork; | |||||
import bubble.model.cloud.BubbleNode; | import bubble.model.cloud.BubbleNode; | ||||
import bubble.model.cloud.CloudService; | import bubble.model.cloud.CloudService; | ||||
import bubble.notify.dns.DnsDriverNotification; | import bubble.notify.dns.DnsDriverNotification; | ||||
@@ -29,12 +28,6 @@ public class DelegatedDnsDriver extends DelegatedCloudServiceDriverBase implemen | |||||
return Arrays.asList(records); | return Arrays.asList(records); | ||||
} | } | ||||
@Override public Collection<DnsRecord> setNetwork(BubbleNetwork network) { | |||||
final BubbleNode delegate = getDelegateNode(); | |||||
final DnsRecord[] records = notificationService.notifySync(delegate, dns_driver_set_network, notification(new DnsDriverNotification(network))); | |||||
return Arrays.asList(records); | |||||
} | |||||
@Override public Collection<DnsRecord> setNode(BubbleNode node) { | @Override public Collection<DnsRecord> setNode(BubbleNode node) { | ||||
final BubbleNode delegate = getDelegateNode(); | final BubbleNode delegate = getDelegateNode(); | ||||
final DnsRecord[] records = notificationService.notifySync(delegate, dns_driver_set_node, notification(new DnsDriverNotification(node))); | final DnsRecord[] records = notificationService.notifySync(delegate, dns_driver_set_node, notification(new DnsDriverNotification(node))); | ||||
@@ -47,7 +47,6 @@ public enum NotificationType { | |||||
// driver-level notifications | // driver-level notifications | ||||
// delegated dns driver notifications | // delegated dns driver notifications | ||||
dns_driver_set_network (DnsRecord[].class), | |||||
dns_driver_set_node (DnsRecord[].class), | dns_driver_set_node (DnsRecord[].class), | ||||
dns_driver_delete_node (DnsRecord[].class), | dns_driver_delete_node (DnsRecord[].class), | ||||
dns_driver_create (DnsRecord[].class), | dns_driver_create (DnsRecord[].class), | ||||
@@ -1,27 +0,0 @@ | |||||
/** | |||||
* Copyright (c) 2020 Bubble, Inc. All rights reserved. | |||||
* For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/ | |||||
*/ | |||||
package bubble.notify.dns; | |||||
import bubble.cloud.dns.DnsServiceDriver; | |||||
import bubble.model.cloud.BubbleDomain; | |||||
import bubble.model.cloud.BubbleNetwork; | |||||
import bubble.model.cloud.notify.ReceivedNotification; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.cobbzilla.util.dns.DnsRecord; | |||||
import java.util.Collection; | |||||
@Slf4j | |||||
public class NotificationHandler_dns_driver_set_network extends NotificationHandler_dns_driver<Collection<DnsRecord>> { | |||||
@Override protected Collection<DnsRecord> handle(ReceivedNotification n, | |||||
DnsDriverNotification dnsNotification, | |||||
BubbleDomain domain, | |||||
BubbleNetwork network, | |||||
DnsServiceDriver dns) { | |||||
return dns.setNetwork(network); | |||||
} | |||||
} |
@@ -795,6 +795,7 @@ public class AccountsResource { | |||||
@Path("/{id}"+EP_PAYMENT_METHODS) | @Path("/{id}"+EP_PAYMENT_METHODS) | ||||
public AccountPaymentMethodsResource getAccountPaymentMethods(@Context ContainerRequest ctx, | public AccountPaymentMethodsResource getAccountPaymentMethods(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountContext c = new AccountContext(ctx, id); | final AccountContext c = new AccountContext(ctx, id); | ||||
return configuration.subResource(AccountPaymentMethodsResource.class, c.account); | return configuration.subResource(AccountPaymentMethodsResource.class, c.account); | ||||
} | } | ||||
@@ -802,6 +803,7 @@ public class AccountsResource { | |||||
@Path("/{id}"+EP_BILLS) | @Path("/{id}"+EP_BILLS) | ||||
public BillsResource getBills(@Context ContainerRequest ctx, | public BillsResource getBills(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountContext c = new AccountContext(ctx, id); | final AccountContext c = new AccountContext(ctx, id); | ||||
return configuration.subResource(BillsResource.class, c.account); | return configuration.subResource(BillsResource.class, c.account); | ||||
} | } | ||||
@@ -809,6 +811,7 @@ public class AccountsResource { | |||||
@Path("/{id}"+EP_PAYMENTS) | @Path("/{id}"+EP_PAYMENTS) | ||||
public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountContext c = new AccountContext(ctx, id); | final AccountContext c = new AccountContext(ctx, id); | ||||
return configuration.subResource(AccountPaymentsResource.class, c.account); | return configuration.subResource(AccountPaymentsResource.class, c.account); | ||||
} | } | ||||
@@ -439,18 +439,21 @@ public class MeResource { | |||||
@Path(EP_PAYMENT_METHODS) | @Path(EP_PAYMENT_METHODS) | ||||
public AccountPaymentMethodsResource getAccountPaymentMethods(@Context ContainerRequest ctx) { | public AccountPaymentMethodsResource getAccountPaymentMethods(@Context ContainerRequest ctx) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final Account caller = userPrincipal(ctx); | final Account caller = userPrincipal(ctx); | ||||
return configuration.subResource(AccountPaymentMethodsResource.class, caller); | return configuration.subResource(AccountPaymentMethodsResource.class, caller); | ||||
} | } | ||||
@Path(EP_BILLS) | @Path(EP_BILLS) | ||||
public BillsResource getBills(@Context ContainerRequest ctx) { | public BillsResource getBills(@Context ContainerRequest ctx) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final Account caller = userPrincipal(ctx); | final Account caller = userPrincipal(ctx); | ||||
return configuration.subResource(BillsResource.class, caller); | return configuration.subResource(BillsResource.class, caller); | ||||
} | } | ||||
@Path(EP_PAYMENTS) | @Path(EP_PAYMENTS) | ||||
public AccountPaymentsResource getPayments(@Context ContainerRequest ctx) { | public AccountPaymentsResource getPayments(@Context ContainerRequest ctx) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final Account caller = userPrincipal(ctx); | final Account caller = userPrincipal(ctx); | ||||
return configuration.subResource(AccountPaymentsResource.class, caller); | return configuration.subResource(AccountPaymentsResource.class, caller); | ||||
} | } | ||||
@@ -361,6 +361,7 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco | |||||
@Path("/{id}"+EP_BILLS) | @Path("/{id}"+EP_BILLS) | ||||
public BillsResource getBills(@Context ContainerRequest ctx, | public BillsResource getBills(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountPlan plan = find(ctx, id); | final AccountPlan plan = find(ctx, id); | ||||
if (plan == null) throw notFoundEx(id); | if (plan == null) throw notFoundEx(id); | ||||
return configuration.subResource(BillsResource.class, account, plan); | return configuration.subResource(BillsResource.class, account, plan); | ||||
@@ -369,6 +370,7 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco | |||||
@Path("/{id}"+EP_PAYMENTS) | @Path("/{id}"+EP_PAYMENTS) | ||||
public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountPlan plan = find(ctx, id); | final AccountPlan plan = find(ctx, id); | ||||
if (plan == null) throw notFoundEx(id); | if (plan == null) throw notFoundEx(id); | ||||
return configuration.subResource(AccountPaymentsResource.class, account, plan); | return configuration.subResource(AccountPaymentsResource.class, account, plan); | ||||
@@ -387,6 +389,7 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco | |||||
) | ) | ||||
public Response getPaymentMethod(@Context ContainerRequest ctx, | public Response getPaymentMethod(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final AccountPlan accountPlan = find(ctx, id); | final AccountPlan accountPlan = find(ctx, id); | ||||
if (accountPlan == null) return notFound(id); | if (accountPlan == null) return notFound(id); | ||||
@@ -99,6 +99,7 @@ public class BillsResource extends ReadOnlyAccountOwnedResource<Bill, BillDAO> { | |||||
@Path("/{id}"+EP_PAYMENTS) | @Path("/{id}"+EP_PAYMENTS) | ||||
public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | public AccountPaymentsResource getPayments(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id) { | @PathParam("id") String id) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final Bill bill = super.find(ctx, id); | final Bill bill = super.find(ctx, id); | ||||
if (bill == null) throw notFoundEx(id); | if (bill == null) throw notFoundEx(id); | ||||
return configuration.subResource(AccountPaymentsResource.class, account, bill); | return configuration.subResource(AccountPaymentsResource.class, account, bill); | ||||
@@ -118,6 +119,7 @@ public class BillsResource extends ReadOnlyAccountOwnedResource<Bill, BillDAO> { | |||||
public Response payBill(@Context ContainerRequest ctx, | public Response payBill(@Context ContainerRequest ctx, | ||||
@PathParam("id") String id, | @PathParam("id") String id, | ||||
AccountPaymentMethod paymentMethod) { | AccountPaymentMethod paymentMethod) { | ||||
configuration.requiresPaymentsEnabled(); | |||||
final Bill bill = super.find(ctx, id); | final Bill bill = super.find(ctx, id); | ||||
if (bill == null) return notFound(id); | if (bill == null) return notFound(id); | ||||
if (bill.paid()) return invalid("err.bill.alreadyPaid"); | if (bill.paid()) return invalid("err.bill.alreadyPaid"); | ||||
@@ -77,6 +77,7 @@ import static org.cobbzilla.util.security.ShaUtil.sha256_file; | |||||
import static org.cobbzilla.util.security.ShaUtil.sha256_hex; | import static org.cobbzilla.util.security.ShaUtil.sha256_hex; | ||||
import static org.cobbzilla.util.system.CommandShell.totalSystemMemory; | import static org.cobbzilla.util.system.CommandShell.totalSystemMemory; | ||||
import static org.cobbzilla.wizard.model.SemanticVersion.isNewerVersion; | import static org.cobbzilla.wizard.model.SemanticVersion.isNewerVersion; | ||||
import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx; | |||||
@Configuration @NoArgsConstructor @Slf4j | @Configuration @NoArgsConstructor @Slf4j | ||||
public class BubbleConfiguration extends PgRestServerConfiguration | public class BubbleConfiguration extends PgRestServerConfiguration | ||||
@@ -420,6 +421,10 @@ public class BubbleConfiguration extends PgRestServerConfiguration | |||||
return peValue != null && Boolean.parseBoolean(peValue.toString()); | return peValue != null && Boolean.parseBoolean(peValue.toString()); | ||||
} | } | ||||
public void requiresPaymentsEnabled () { | |||||
if (!paymentsEnabled()) throw invalidEx("err_noPaymentMethods"); | |||||
} | |||||
@Getter @Setter private Boolean requireSendMetrics; | @Getter @Setter private Boolean requireSendMetrics; | ||||
public boolean requireSendMetrics () { return bool(requireSendMetrics); } | public boolean requireSendMetrics () { return bool(requireSendMetrics); } | ||||
@@ -252,8 +252,10 @@ public class StandardNetworkService implements NetworkService { | |||||
jobFutures.add(backgroundJobs.submit(startJob)); | jobFutures.add(backgroundJobs.submit(startJob)); | ||||
// Create DNS records for node | // Create DNS records for node | ||||
final NodeDnsJob dnsJob = new NodeDnsJob(cloudDAO, domain, network, node, configuration); | |||||
jobFutures.add(backgroundJobs.submit(dnsJob)); | |||||
if (computeDriver.supportsDns()) { | |||||
final NodeDnsJob dnsJob = new NodeDnsJob(cloudDAO, domain, network, node, configuration); | |||||
jobFutures.add(backgroundJobs.submit(dnsJob)); | |||||
} | |||||
// Prepare ansible roles | // Prepare ansible roles | ||||
// We must wait until after server is started, because some roles require ip4 in vars | // We must wait until after server is started, because some roles require ip4 in vars | ||||
@@ -291,7 +293,7 @@ public class StandardNetworkService implements NetworkService { | |||||
// run ansible | // run ansible | ||||
final String sshArgs | final String sshArgs | ||||
= "-p 1202 " | |||||
= "-p " + computeDriver.getSshPort(node) + " " | |||||
+ "-o UserKnownHostsFile=/dev/null " | + "-o UserKnownHostsFile=/dev/null " | ||||
+ "-o StrictHostKeyChecking=no " | + "-o StrictHostKeyChecking=no " | ||||
+ "-o PreferredAuthentications=publickey " | + "-o PreferredAuthentications=publickey " | ||||
@@ -722,11 +724,6 @@ public class StandardNetworkService implements NetworkService { | |||||
network.setState(BubbleNetworkState.starting); | network.setState(BubbleNetworkState.starting); | ||||
networkDAO.update(network); | networkDAO.update(network); | ||||
// ensure NS records for network are in DNS | |||||
final BubbleDomain domain = domainDAO.findByUuid(network.getDomain()); | |||||
final CloudService dns = cloudDAO.findByUuid(domain.getPublicDns()); | |||||
dns.getDnsDriver(configuration).setNetwork(network); | |||||
final NewNodeNotification newNodeRequest = new NewNodeNotification() | final NewNodeNotification newNodeRequest = new NewNodeNotification() | ||||
.setFork(network.fork()) | .setFork(network.fork()) | ||||
.setLaunchType(network.getLaunchType()) | .setLaunchType(network.getLaunchType()) | ||||
@@ -787,11 +784,6 @@ public class StandardNetworkService implements NetworkService { | |||||
network.setState(BubbleNetworkState.starting); | network.setState(BubbleNetworkState.starting); | ||||
networkDAO.update(network); | networkDAO.update(network); | ||||
// ensure NS records for network are in DNS | |||||
final BubbleDomain domain = domainDAO.findByUuid(network.getDomain()); | |||||
final CloudService dns = cloudDAO.findByUuid(domain.getPublicDns()); | |||||
dns.getDnsDriver(configuration).setNetwork(network); | |||||
final CloudAndRegion cloudAndRegion = geoService.selectCloudAndRegion(network, netLocation); | final CloudAndRegion cloudAndRegion = geoService.selectCloudAndRegion(network, netLocation); | ||||
final String restoreKey = randomAlphanumeric(RESTORE_KEY_LEN).toUpperCase(); | final String restoreKey = randomAlphanumeric(RESTORE_KEY_LEN).toUpperCase(); | ||||
restoreService.registerRestore(restoreKey, new NetworkKeys()); | restoreService.registerRestore(restoreKey, new NetworkKeys()); | ||||
@@ -4,7 +4,7 @@ | |||||
*/ | */ | ||||
package bubble.service.packer; | package bubble.service.packer; | ||||
import bubble.cloud.CloudRegion; | |||||
import bubble.cloud.compute.ComputeServiceDriver; | |||||
import bubble.cloud.compute.PackerImage; | import bubble.cloud.compute.PackerImage; | ||||
import com.fasterxml.jackson.databind.JsonNode; | import com.fasterxml.jackson.databind.JsonNode; | ||||
import com.fasterxml.jackson.databind.node.ArrayNode; | import com.fasterxml.jackson.databind.node.ArrayNode; | ||||
@@ -21,17 +21,11 @@ public class PackerBuild { | |||||
@Getter @Setter private String packer_run_uuid; | @Getter @Setter private String packer_run_uuid; | ||||
@Getter @Setter private JsonNode custom_data; | @Getter @Setter private JsonNode custom_data; | ||||
public PackerImage toPackerImage(String name) { | |||||
final String[] parts = artifact_id.split(":"); | |||||
final String[] regionNames = parts[0].split(","); | |||||
final CloudRegion[] regions = new CloudRegion[regionNames.length]; | |||||
for (int i=0; i<regionNames.length; i++) { | |||||
regions[i] = new CloudRegion().setInternalName(regionNames[i]); | |||||
} | |||||
final String id = parts[1]; | |||||
public PackerImage toPackerImage(String name, ComputeServiceDriver computeDriver) { | |||||
return new PackerImage() | return new PackerImage() | ||||
.setId(id) | |||||
.setId(computeDriver.getPackerImageId(name, this)) | |||||
.setName(name) | .setName(name) | ||||
.setRegions(regions); | |||||
.setRegions(computeDriver.getRegions(this)); | |||||
} | } | ||||
} | } |
@@ -148,6 +148,11 @@ public class PackerJob implements Callable<List<PackerImage>> { | |||||
final ComputeServiceDriver computeDriver = cloud.getComputeDriver(configuration); | final ComputeServiceDriver computeDriver = cloud.getComputeDriver(configuration); | ||||
final PackerConfig packerConfig = computeConfig.getPacker(); | final PackerConfig packerConfig = computeConfig.getPacker(); | ||||
if (!computeDriver.supportsPacker(installType)) { | |||||
setImagesRefs(); | |||||
return Collections.emptyList(); | |||||
} | |||||
// create handlebars context | // create handlebars context | ||||
final Map<String, Object> ctx = new HashMap<>(); | final Map<String, Object> ctx = new HashMap<>(); | ||||
final CloudCredentials creds = cloud.getCredentials(); | final CloudCredentials creds = cloud.getCredentials(); | ||||
@@ -174,12 +179,12 @@ public class PackerJob implements Callable<List<PackerImage>> { | |||||
if (!env.containsKey("HOME")) env.put("HOME", HOME_DIR); | if (!env.containsKey("HOME")) env.put("HOME", HOME_DIR); | ||||
// Docker builder requires "docker" command to be on our path | // Docker builder requires "docker" command to be on our path | ||||
// It is usually in /usr/local/bin | |||||
// It is usually /usr/local/bin on macosx and /usr/bin on linux | |||||
// May need to make this more flexible if docker is elsewhere, or other tools/paths are needed | // May need to make this more flexible if docker is elsewhere, or other tools/paths are needed | ||||
if (env.containsKey("PATH")) { | if (env.containsKey("PATH")) { | ||||
env.put("PATH", "${PATH}:/usr/local/bin"); | |||||
env.put("PATH", "${PATH}:/usr/local/bin:/usr/bin"); | |||||
} else { | } else { | ||||
env.put("PATH", "/usr/local/bin"); | |||||
env.put("PATH", "/usr/local/bin:/usr/bin"); | |||||
} | } | ||||
ctx.put(VARIABLES_VAR, packerConfig.getVars()); | ctx.put(VARIABLES_VAR, packerConfig.getVars()); | ||||
@@ -304,7 +309,7 @@ public class PackerJob implements Callable<List<PackerImage>> { | |||||
if (empty(builds)) { | if (empty(builds)) { | ||||
return die("Error executing packer: no builds found"); | return die("Error executing packer: no builds found"); | ||||
} | } | ||||
images.addAll(Arrays.stream(builds).map(b -> b.toPackerImage(imageName)).collect(Collectors.toList())); | |||||
images.addAll(Arrays.stream(builds).map(b -> b.toPackerImage(imageName, computeDriver)).collect(Collectors.toList())); | |||||
} else { | } else { | ||||
final List<PackerImage> finalizedImages = computeDriver.finalizeIncompletePackerRun(commandResult, installType); | final List<PackerImage> finalizedImages = computeDriver.finalizeIncompletePackerRun(commandResult, installType); | ||||
@@ -1 +1,3 @@ | |||||
bubble.version=Adventure 1.5.2 | |||||
# Do not edit this file directly | |||||
# Use _set_version to update the Bubble version in all files | |||||
bubble.version=Adventure 1.5.1 |
@@ -28,7 +28,7 @@ function kill_bg_jobs { | |||||
kill %${j} | kill %${j} | ||||
done | done | ||||
{{#if isNode}} | {{#if isNode}} | ||||
if [[ ! -z "${ALGO_LOG}" && -f "${ALGO_LOG}" ]] ; then | |||||
if [[ -n "${ALGO_LOG}" && -f "${ALGO_LOG}" ]] ; then | |||||
rm -f ${ALGO_LOG} | rm -f ${ALGO_LOG} | ||||
fi | fi | ||||
{{/if}} | {{/if}} | ||||
@@ -166,9 +166,10 @@ | |||||
"type": "docker", | "type": "docker", | ||||
"image": "<<os.name>>", | "image": "<<os.name>>", | ||||
"export_path": "<<packerImageName>>.tar", | "export_path": "<<packerImageName>>.tar", | ||||
"cap_add": ["NET_ADMIN", "SYS_ADMIN", "SYS_MODULE"], | |||||
"changes": [ | "changes": [ | ||||
"LABEL bubble_image=<<packerImageName>>", | "LABEL bubble_image=<<packerImageName>>", | ||||
"EXPOSE 80 443 1202" | |||||
"EXPOSE 22 80 443 1080 1202 1443 8888 9999 53/udp 500/udp 4500/udp 51820/udp" | |||||
] | ] | ||||
}, | }, | ||||
"post": { | "post": { | ||||
@@ -55,7 +55,7 @@ log "Regenerating algo config..." | |||||
java -cp /home/bubble/api/bubble.jar bubble.main.BubbleMain generate-algo-conf --algo-config ${ALGO_CONFIG}.hbs || die "Error writing algo config.cfg" | java -cp /home/bubble/api/bubble.jar bubble.main.BubbleMain generate-algo-conf --algo-config ${ALGO_CONFIG}.hbs || die "Error writing algo config.cfg" | ||||
NEW_ALGO_CONFIG_SHA="$(sha256sum ${ALGO_CONFIG} | cut -f1 -d' ')" | NEW_ALGO_CONFIG_SHA="$(sha256sum ${ALGO_CONFIG} | cut -f1 -d' ')" | ||||
if [[ ! -z "${ALGO_CONFIG_SHA}" && "${ALGO_CONFIG_SHA}" == "${NEW_ALGO_CONFIG_SHA}" ]] ; then | |||||
if [[ -n "${ALGO_CONFIG_SHA}" && "${ALGO_CONFIG_SHA}" == "${NEW_ALGO_CONFIG_SHA}" ]] ; then | |||||
log "Algo configuration is unchanged, not refreshing: ${ALGO_CONFIG}" | log "Algo configuration is unchanged, not refreshing: ${ALGO_CONFIG}" | ||||
else | else | ||||
@@ -28,7 +28,7 @@ while : ; do | |||||
transfer="" | transfer="" | ||||
IFS=$'\n' | IFS=$'\n' | ||||
for line in $(wg show all) ; do | for line in $(wg show all) ; do | ||||
if [[ ! -z "${peer}" ]] ; then | |||||
if [[ -n "${peer}" ]] ; then | |||||
if [[ $(echo "${line}" | tr -d ' ') == endpoint* ]] ; then | if [[ $(echo "${line}" | tr -d ' ') == endpoint* ]] ; then | ||||
endpoint="$(echo "${line}" | cut -d: -f2- | awk '{$1=$1};1')" | endpoint="$(echo "${line}" | cut -d: -f2- | awk '{$1=$1};1')" | ||||
@@ -71,16 +71,16 @@ while : ; do | |||||
fi | fi | ||||
if [[ ${line} == peer* ]] ; then | if [[ ${line} == peer* ]] ; then | ||||
if [[ ! -z "${peer}" ]] ; then | |||||
if [[ ! -z "${device}" ]] ; then | |||||
if [[ -n "${peer}" ]] ; then | |||||
if [[ -n "${device}" ]] ; then | |||||
echo "in-loop, setting stats for peer ${peer} device ${device}" | echo "in-loop, setting stats for peer ${peer} device ${device}" | ||||
if [[ ! -z "${endpoint}" ]] ; then | |||||
if [[ -n "${endpoint}" ]] ; then | |||||
echo "set wg_device_status_${device}_endpoint \"${endpoint}\"" | redis-cli | echo "set wg_device_status_${device}_endpoint \"${endpoint}\"" | redis-cli | ||||
fi | fi | ||||
if [[ ! -z "${latest_handshake}" ]] ; then | |||||
if [[ -n "${latest_handshake}" ]] ; then | |||||
echo "set wg_device_status_${device}_latestHandshake \"${latest_handshake}\"" | redis-cli | echo "set wg_device_status_${device}_latestHandshake \"${latest_handshake}\"" | redis-cli | ||||
fi | fi | ||||
if [[ ! -z "${transfer}" ]] ; then | |||||
if [[ -n "${transfer}" ]] ; then | |||||
echo "set wg_device_status_${device}_transfer \"${transfer}\"" | redis-cli | echo "set wg_device_status_${device}_transfer \"${transfer}\"" | redis-cli | ||||
fi | fi | ||||
fi | fi | ||||
@@ -93,16 +93,16 @@ while : ; do | |||||
echo "in-loop, set peer: ${peer}" | echo "in-loop, set peer: ${peer}" | ||||
fi | fi | ||||
done | done | ||||
if [[ ! -z "${peer}" ]] ; then | |||||
if [[ -n "${peer}" ]] ; then | |||||
echo "end-of-loop, setting stats for peer ${peer} device ${device}" | echo "end-of-loop, setting stats for peer ${peer} device ${device}" | ||||
if [[ ! -z "${device}" ]] ; then | |||||
if [[ ! -z "${endpoint}" ]] ; then | |||||
if [[ -n "${device}" ]] ; then | |||||
if [[ -n "${endpoint}" ]] ; then | |||||
echo "set wg_device_status_${device}_endpoint \"${endpoint}\"" | redis-cli | echo "set wg_device_status_${device}_endpoint \"${endpoint}\"" | redis-cli | ||||
fi | fi | ||||
if [[ ! -z "${latest_handshake}" ]] ; then | |||||
if [[ -n "${latest_handshake}" ]] ; then | |||||
echo "set wg_device_status_${device}_latestHandshake \"${latest_handshake}\"" | redis-cli | echo "set wg_device_status_${device}_latestHandshake \"${latest_handshake}\"" | redis-cli | ||||
fi | fi | ||||
if [[ ! -z "${transfer}" ]] ; then | |||||
if [[ -n "${transfer}" ]] ; then | |||||
echo "set wg_device_status_${device}_transfer \"${transfer}\"" | redis-cli | echo "set wg_device_status_${device}_transfer \"${transfer}\"" | redis-cli | ||||
fi | fi | ||||
fi | fi | ||||
@@ -45,7 +45,7 @@ function verify_api_ok { | |||||
done | done | ||||
log "verify_api_ok: while loop ended, CURL_STATUS=${CURL_STATUS}, (date - start)=$(expr $(date +%s) - ${START_VERIFY}), VERIFY_TIMEOUT=${VERIFY_TIMEOUT}" | log "verify_api_ok: while loop ended, CURL_STATUS=${CURL_STATUS}, (date - start)=$(expr $(date +%s) - ${START_VERIFY}), VERIFY_TIMEOUT=${VERIFY_TIMEOUT}" | ||||
if [[ ! -z "${CURL_STATUS}" && ${CURL_STATUS} -eq 200 ]] ; then | |||||
if [[ -n "${CURL_STATUS}" && ${CURL_STATUS} -eq 200 ]] ; then | |||||
echo "ok" | echo "ok" | ||||
else | else | ||||
echo "error" | echo "error" | ||||
@@ -87,7 +87,7 @@ if [[ "${3}" == "INIT" ]] ; then | |||||
exit 0 | exit 0 | ||||
fi | fi | ||||
if [[ ! -z "${DROP_AND_RECREATE}" && "${DROP_AND_RECREATE}" == "drop" ]] ; then | |||||
if [[ -n "${DROP_AND_RECREATE}" && "${DROP_AND_RECREATE}" == "drop" ]] ; then | |||||
dropdb ${DB_NAME} || echo "error dropping DB ${DB_NAME} (will continue)" | dropdb ${DB_NAME} || echo "error dropping DB ${DB_NAME} (will continue)" | ||||
dropuser ${DB_USER} || echo "error dropping DB user ${DB_USER} (will continue)" | dropuser ${DB_USER} || echo "error dropping DB user ${DB_USER} (will continue)" | ||||
uuid > ${BUBBLE_HOME}/.BUBBLE_PG_PASSWORD | uuid > ${BUBBLE_HOME}/.BUBBLE_PG_PASSWORD | ||||
@@ -34,7 +34,7 @@ for key in $(echo "${CURRENT_KEYS_SQL}" | PGPASSWORD="$(cat /home/bubble/.BUBBLE | |||||
continue | continue | ||||
fi | fi | ||||
KEY="$(bdecrypt "${key}" 2> /dev/null)" | KEY="$(bdecrypt "${key}" 2> /dev/null)" | ||||
if [[ ! -z "${KEY}" && "${KEY}" == ssh-rsa* ]] ; then | |||||
if [[ -n "${KEY}" && "${KEY}" == ssh-rsa* ]] ; then | |||||
log "Adding authorized key: $(echo "${KEY}" | tr -d '\n')" | log "Adding authorized key: $(echo "${KEY}" | tr -d '\n')" | ||||
echo "${KEY}" >> ${NEW_KEYS} | echo "${KEY}" >> ${NEW_KEYS} | ||||
KEY_COUNT=$(expr ${KEY_COUNT} + 1) | KEY_COUNT=$(expr ${KEY_COUNT} + 1) | ||||
@@ -0,0 +1,5 @@ | |||||
- name: Install packages missing on docker ubuntu | |||||
apt: | |||||
name: [ 'curl', 'cron', 'iptables', 'openssh-server' ] | |||||
state: present | |||||
update_cache: yes |
@@ -94,3 +94,6 @@ | |||||
system: yes | system: yes | ||||
home: /home/bubble-flex | home: /home/bubble-flex | ||||
when: install_type == 'node' | when: install_type == 'node' | ||||
- include: docker.yml | |||||
when: packer_builder_type == 'docker' |
@@ -109,6 +109,7 @@ | |||||
owner: root | owner: root | ||||
group: root | group: root | ||||
mode: 0400 | mode: 0400 | ||||
when: fw_enable_ssh | |||||
- name: Install SSH fail2ban settings | - name: Install SSH fail2ban settings | ||||
copy: | copy: | ||||
@@ -117,10 +118,6 @@ | |||||
owner: root | owner: root | ||||
group: root | group: root | ||||
mode: 0400 | mode: 0400 | ||||
when: fw_enable_ssh | |||||
- include: rules.yml | - include: rules.yml | ||||
- supervisorctl: | |||||
name: bubble_peer_manager | |||||
state: restarted | |||||
when: fw_enable_admin |
@@ -86,7 +86,7 @@ function healthCheck { | |||||
while [[ $(expr $(date +%s) - ${START}) -le ${HEALTH_CHECK_TIMEOUT} ]] ; do | while [[ $(expr $(date +%s) - ${START}) -le ${HEALTH_CHECK_TIMEOUT} ]] ; do | ||||
# log "Performing health check on mitm${MITM_PORT} via ${HC_URL} ..." | # log "Performing health check on mitm${MITM_PORT} via ${HC_URL} ..." | ||||
CURL_OUT="$(curl --silent --connect-timeout 2 --max-time 2 ${HC_URL} 2>> ${LOG})" | CURL_OUT="$(curl --silent --connect-timeout 2 --max-time 2 ${HC_URL} 2>> ${LOG})" | ||||
if [[ ! -z ${CURL_OUT} && ${CURL_OUT} == "OK" ]] ; then | |||||
if [[ -n ${CURL_OUT} && ${CURL_OUT} == "OK" ]] ; then | |||||
# log "Health check on mitm${MITM_PORT} via ${HC_URL} : OK" | # log "Health check on mitm${MITM_PORT} via ${HC_URL} : OK" | ||||
echo -n "OK" | echo -n "OK" | ||||
return | return | ||||
@@ -24,7 +24,7 @@ if [[ -f ${MITM_PORT_FILE} ]] ; then | |||||
done | done | ||||
if [[ -s ${MITM_PORT_FILE} ]] ; then | if [[ -s ${MITM_PORT_FILE} ]] ; then | ||||
MITM_PORT="$(cat ${MITM_PORT_FILE})" | MITM_PORT="$(cat ${MITM_PORT_FILE})" | ||||
if [[ ! -z "${MITM_PORT}" && ${MITM_PORT} -ne ${PORT} ]] ; then | |||||
if [[ -n "${MITM_PORT}" && ${MITM_PORT} -ne ${PORT} ]] ; then | |||||
log "Our port (${PORT}) is not the primary mitm port (${MITM_PORT}), delaying startup by 30 seconds" | log "Our port (${PORT}) is not the primary mitm port (${MITM_PORT}), delaying startup by 30 seconds" | ||||
sleep 30s | sleep 30s | ||||
fi | fi | ||||
@@ -7,18 +7,30 @@ | |||||
state: present | state: present | ||||
update_cache: yes | update_cache: yes | ||||
- sysctl: | |||||
name: net.ipv4.ip_forward | |||||
- name: Set sysctl networking settings to allow IP forwarding | |||||
sysctl: | |||||
name: "{{ item }}" | |||||
value: 1 | value: 1 | ||||
sysctl_set: yes | sysctl_set: yes | ||||
- sysctl: | |||||
name: net.ipv6.conf.all.forwarding | |||||
value: 1 | |||||
sysctl_set: yes | |||||
- sysctl: | |||||
with_items: [ 'net.ipv4.ip_forward', 'net.ipv4.conf.all.forwarding', 'net.ipv6.conf.all.forwarding' ] | |||||
when: packer_builder_type != 'docker' | |||||
- name: Verify sysctl networking settings are enabled in host to allow IP forwarding | |||||
shell: "if [[ $(sysctl -n {{ item }}) -ne 1 ]] ; then echo 'sysctl validation failed: {{ item }} = 1'; exit 1 ; fi" | |||||
with_items: [ 'net.ipv4.ip_forward', 'net.ipv4.conf.all.forwarding', 'net.ipv6.conf.all.forwarding' ] | |||||
when: packer_builder_type == 'docker' | |||||
- name: Set sysctl setting net.ipv4.conf.all.send_redirects = 0 | |||||
sysctl: | |||||
name: net.ipv4.conf.all.send_redirects | name: net.ipv4.conf.all.send_redirects | ||||
value: 0 | value: 0 | ||||
sysctl_set: yes | sysctl_set: yes | ||||
when: packer_builder_type != 'docker' | |||||
- name: Verify sysctl networking settings are disabled in host to allow IP forwarding | |||||
shell: "if [[ $(sysctl -n {{ item }}) -ne 0 ]] ; then echo 'sysctl validation failed: {{ item }} = 0'; exit 1 ; fi" | |||||
with_items: [ 'net.ipv4.conf.all.send_redirects' ] | |||||
when: packer_builder_type == 'docker' | |||||
- name: Create mitm user | - name: Create mitm user | ||||
user: | user: | ||||
@@ -133,9 +133,10 @@ | |||||
"type": "docker", | "type": "docker", | ||||
"image": "<<os.name>>", | "image": "<<os.name>>", | ||||
"export_path": "<<packerImageName>>.tar", | "export_path": "<<packerImageName>>.tar", | ||||
"cap_add": ["NET_ADMIN", "SYS_ADMIN", "SYS_MODULE"], | |||||
"changes": [ | "changes": [ | ||||
"LABEL bubble_image=<<packerImageName>>", | "LABEL bubble_image=<<packerImageName>>", | ||||
"EXPOSE 80 443 1202" | |||||
"EXPOSE 22 80 443 1080 1202 1443 8888 9999 53/udp 500/udp 4500/udp 51820/udp" | |||||
] | ] | ||||
}, | }, | ||||
"post": { | "post": { | ||||
@@ -48,7 +48,7 @@ if [[ -z "${VERSION}" ]] ; then | |||||
die "Error determining version from: ${META_FILE}" | die "Error determining version from: ${META_FILE}" | ||||
fi | fi | ||||
DOCKER_REPO="getbubble" | DOCKER_REPO="getbubble" | ||||
if [[ ! -z "${BUBBLE_DOCKER_REPO}" ]] ; then | |||||
if [[ -n "${BUBBLE_DOCKER_REPO}" ]] ; then | |||||
DOCKER_REPO="${BUBBLE_DOCKER_REPO}" | DOCKER_REPO="${BUBBLE_DOCKER_REPO}" | ||||
fi | fi | ||||
BUBBLE_TAG="${DOCKER_REPO}/launcher:${VERSION}" | BUBBLE_TAG="${DOCKER_REPO}/launcher:${VERSION}" | ||||
@@ -73,7 +73,7 @@ elif [[ "${MODE}" == "run" ]] ; then | |||||
export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} | export LETSENCRYPT_EMAIL=${LETSENCRYPT_EMAIL} | ||||
" >> "${BUBBLE_ENV}" | " >> "${BUBBLE_ENV}" | ||||
fi | fi | ||||
if [[ ! -z "${BUBBLE_RUN_SLIM}" && "${BUBBLE_RUN_SLIM}" == "true" ]] ; then | |||||
if [[ -n "${BUBBLE_RUN_SLIM}" && "${BUBBLE_RUN_SLIM}" == "true" ]] ; then | |||||
RUN_TAG="${BUBBLE_SLIM_TAG}" | RUN_TAG="${BUBBLE_SLIM_TAG}" | ||||
else | else | ||||
RUN_TAG="${BUBBLE_TAG}" | RUN_TAG="${BUBBLE_TAG}" | ||||
@@ -8,12 +8,13 @@ | |||||
<parent> | <parent> | ||||
<groupId>org.cobbzilla</groupId> | <groupId>org.cobbzilla</groupId> | ||||
<artifactId>cobbzilla-parent</artifactId> | <artifactId>cobbzilla-parent</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<version>2.0.1</version> | |||||
</parent> | </parent> | ||||
<groupId>bubble</groupId> | <groupId>bubble</groupId> | ||||
<artifactId>bubble</artifactId> | <artifactId>bubble</artifactId> | ||||
<version>1.0.0-SNAPSHOT</version> | |||||
<!-- @@BUBBLE_VERSION@@ this comment must remain above the version tag so that _set_version can update it --> | |||||
<version>1.5.1</version> | |||||
<packaging>pom</packaging> | <packaging>pom</packaging> | ||||
<licenses> | <licenses> | ||||
@@ -1 +1 @@ | |||||
Subproject commit 072a11decff65461f12f47e5dae763b56a5a3247 | |||||
Subproject commit 7b5ff5887a00ffd89a96f22329315e4867ed09c6 |
@@ -1 +1 @@ | |||||
Subproject commit 52e7a99a6625f7e1db998179fa5a3cff90acb1a1 | |||||
Subproject commit 8e7003de03983a4a683702436b89469dac0ffe0a |
@@ -1 +1 @@ | |||||
Subproject commit e8914281714dd6d2ec2caee9dadc5fc500e16a26 | |||||
Subproject commit 8647e5f4429377e033b4605ae37c55717fef3e44 |
@@ -1 +1 @@ | |||||
Subproject commit 0bce26d2cc10c4325a0a48d253463205609febe0 | |||||
Subproject commit 50dbd4340e4444916023e63d2d5e97469cc17de3 |
@@ -1 +1 @@ | |||||
Subproject commit f6755a30ad8a2097a5bc439aa798fc8ef6dc6507 | |||||
Subproject commit 19ea8b1da6108ace0cde98a9202ad6301976ebc3 |