Browse Source

WIP. sage nearly launches in docker

tags/v1.5.4
Jonathan Cobb 3 years ago
parent
commit
5c1092bb94
16 changed files with 65 additions and 44 deletions
  1. +3
    -0
      bubble-server/src/main/java/bubble/cloud/compute/ComputeServiceDriver.java
  2. +10
    -4
      bubble-server/src/main/java/bubble/cloud/compute/docker/DockerComputeDriver.java
  3. +19
    -11
      bubble-server/src/main/java/bubble/dao/cloud/BubbleNodeDAO.java
  4. +4
    -3
      bubble-server/src/main/java/bubble/server/listener/BubbleFirstTimeListener.java
  5. +7
    -2
      bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java
  6. +1
    -1
      bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java
  7. +1
    -1
      bubble-server/src/main/resources/ansible/install_local.sh.hbs
  8. +1
    -1
      bubble-server/src/main/resources/ansible/roles/bubble/files/bubble_role.json
  9. +1
    -1
      bubble-server/src/main/resources/ansible/roles/bubble/templates/bubble.env.j2
  10. +2
    -1
      bubble-server/src/main/resources/ansible/roles/finalizer/files/bubble_role.json
  11. +9
    -0
      bubble-server/src/main/resources/ansible/roles/finalizer/tasks/main.yml
  12. +2
    -1
      bubble-server/src/main/resources/ansible/roles/nginx/files/bubble_role.json
  13. +4
    -0
      bubble-server/src/main/resources/ansible/roles/nginx/tasks/main.yml
  14. +0
    -13
      bubble-server/src/main/resources/bubble/host-prefixes.txt
  15. +0
    -4
      bubble-server/src/main/resources/packer/roles/finalizer/tasks/main.yml
  16. +1
    -1
      utils/cobbzilla-utils

+ 3
- 0
bubble-server/src/main/java/bubble/cloud/compute/ComputeServiceDriver.java View File

@@ -72,4 +72,7 @@ public interface ComputeServiceDriver extends CloudServiceDriver, RegionalServic
default void addLaunchContext(Map<String, Object> ctx) { addLaunchContext(ctx, ""); }
default void addLaunchContext(Map<String, Object> ctx, String prefix) {}

default String getNodeIp4(BubbleNode node) { return node.getIp4(); }
default String getNodeIp6(BubbleNode node) { return node.getIp6(); }

}

+ 10
- 4
bubble-server/src/main/java/bubble/cloud/compute/docker/DockerComputeDriver.java View File

@@ -39,6 +39,8 @@ import static org.cobbzilla.util.io.FileUtil.abs;
import static org.cobbzilla.util.io.StreamUtil.loadResourceAsStream;
import static org.cobbzilla.util.io.StreamUtil.stream2file;
import static org.cobbzilla.util.json.JsonUtil.json;
import static org.cobbzilla.util.network.NetworkUtil.IPv4_LOCALHOST;
import static org.cobbzilla.util.network.NetworkUtil.IPv6_LOCALHOST;
import static org.cobbzilla.util.system.Sleep.sleep;

@Slf4j
@@ -90,9 +92,10 @@ public class DockerComputeDriver extends ComputeServiceDriverBase {

private final Map<String, Map<Integer, Integer>> portMappings = new ConcurrentHashMap<>();

@Override public int getSshPort(BubbleNode node) {
return portMappings.get(node.getUuid()).get(22);
}
@Override public int getSshPort(BubbleNode node) { return portMappings.get(node.getUuid()).get(22); }

@Override public String getNodeIp4(BubbleNode node) { return IPv4_LOCALHOST; }
@Override public String getNodeIp6(BubbleNode node) { return IPv6_LOCALHOST; }

@Getter(lazy=true) private final DockerClient dockerClient = initDockerClient();
private DockerClient initDockerClient() {
@@ -182,9 +185,12 @@ public class DockerComputeDriver extends ComputeServiceDriverBase {
final Integer adminPort = portMap.get(8090);
if (adminPort == null) return die("start("+node.id()+"): admin port mapping not found in port map: "+json(portMap));

final String ip4 = nodeDAO.randomLocalhostIp4();
final String ip6 = nodeDAO.randomLocalhostIp6();
return node.setState(BubbleNodeState.running)
.setAdminPort(adminPort)
.setIp4(nodeDAO.randomLocalhostIp4())
.setIp4(ip4)
.setIp6(ip6)
.setFqdn(node.getIp4());
}
}


+ 19
- 11
bubble-server/src/main/java/bubble/dao/cloud/BubbleNodeDAO.java View File

@@ -21,7 +21,7 @@ import static bubble.ApiConstants.ROOT_NETWORK_UUID;
import static bubble.ApiConstants.newNodeHostname;
import static bubble.model.cloud.BubbleNodeState.running;
import static org.cobbzilla.util.daemon.ZillaRuntime.die;
import static org.cobbzilla.util.network.NetworkUtil.isLocalIpv4;
import static org.cobbzilla.util.network.NetworkUtil.*;
import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;
import static org.hibernate.criterion.Restrictions.isNotNull;

@@ -110,23 +110,31 @@ public class BubbleNodeDAO extends AccountOwnedEntityDAO<BubbleNode> {

public List<BubbleNode> findWithIp4() { return list(criteria().add(isNotNull("ip4"))); }

public BubbleNode findByIp4(String ip4) { return isLocalIpv4(ip4) ? null : findByUniqueField("ip4", ip4); }
public BubbleNode findByIp4(String ip4) { return isLocalIpv4(ip4) ? null : _findByIp4(ip4); }

public BubbleNode _findByIp4(String ip4) { return findByUniqueField("ip4", ip4); }
public BubbleNode _findByIp6(String ip6) { return findByUniqueField("ip6", ip6); }

public String randomLocalhostIp4 () {
// first try a random number in the last slot
int x = RandomUtils.nextInt(1, 255);
String testIp = "127.0.0." + x;
if (findByIp4(testIp) == null) return testIp;

// keep trying random numbers, incrementing the other octets
for (int i=0; i<254; i++) {
for (int j=0; j<254; j++) {
x = RandomUtils.nextInt(1, 255);
testIp = "127."+i+"."+j+"."+x;
if (findByIp4(testIp) == null) return testIp;
}
if (_findByIp4(testIp) == null) return testIp;

// keep trying random numbers
for (int i=0; i<100; i++) {
testIp = randomLocalIp4();
if (_findByIp4(testIp) == null) return testIp;
}
return die("randomLocalhostIp4: ran out of tries!");
}

public String randomLocalhostIp6 () {
for (int i=0; i<100; i++) {
final String testIp = randomLocalIp6();
if (_findByIp6(testIp) == null) return testIp;
}
return die("randomLocalhostIp6: ran out of tries!");
}

}

+ 4
- 3
bubble-server/src/main/java/bubble/server/listener/BubbleFirstTimeListener.java View File

@@ -55,11 +55,11 @@ public class BubbleFirstTimeListener extends RestServerLifecycleListenerBase<Bub
redis.set(configuration.getBean(RedisService.class));

final AccountDAO accountDAO = configuration.getBean(AccountDAO.class);
final var network = configuration.getThisNetwork();
final BubbleNetwork network = configuration.getThisNetwork();
if (FIRST_TIME_FILE.exists()) {
try {
try {
final var firstTimeType = FirstTimeType.fromString(toStringOrDie(FIRST_TIME_FILE));
final FirstTimeType firstTimeType = FirstTimeType.fromString(toStringOrDie(FIRST_TIME_FILE));
updateNetworkState(configuration, network, firstTimeType);
} catch (Exception e) {
log.warn("Cannot open and/or read/parse first time file " + FIRST_TIME_FILE.getAbsolutePath());
@@ -112,7 +112,8 @@ public class BubbleFirstTimeListener extends RestServerLifecycleListenerBase<Bub
}
}

private void updateNetworkState(@NonNull final BubbleConfiguration config, @NonNull final BubbleNetwork network,
private void updateNetworkState(@NonNull final BubbleConfiguration config,
@NonNull final BubbleNetwork network,
@NonNull final FirstTimeType firstTimeType) {
if (network.getState() == BubbleNetworkState.starting) {
network.setState(firstTimeType == FirstTimeType.restore ? BubbleNetworkState.restoring


+ 7
- 2
bubble-server/src/main/java/bubble/service/cloud/AnsiblePrepService.java View File

@@ -171,12 +171,17 @@ public class AnsiblePrepService {

private int jvmMaxRam(ComputeNodeSize nodeSize, AnsibleInstallType installType) {
final int memoryMB = nodeSize.getMemoryMB();
if (installType == AnsibleInstallType.sage) return (int) (((double) memoryMB) * 0.6d);
if (installType == AnsibleInstallType.sage) {
// at least 256MB, up to 60% of system memory
return Math.max(256, (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
return (int) (((double) memoryMB) * 0.19d);
// set floor at 200MB, might be able to go lower.
return Math.max(200, (int) (((double) memoryMB) * 0.19d));
}

private boolean shouldEnableOpenApi(AnsibleInstallType installType, ComputeNodeSize nodeSize) {


+ 1
- 1
bubble-server/src/main/java/bubble/service/cloud/StandardNetworkService.java View File

@@ -304,7 +304,7 @@ public class StandardNetworkService implements NetworkService {
+ "-o StrictHostKeyChecking=no "
+ "-o PreferredAuthentications=publickey "
+ "-i " + abs(sshKeyFile);
final String sshTarget = node.getUser() + "@" + node.getIp4();
final String sshTarget = node.getUser() + "@" + computeDriver.getNodeIp4(node);

boolean setupOk = false;
final String nodeUser = node.getUser();


+ 1
- 1
bubble-server/src/main/resources/ansible/install_local.sh.hbs View File

@@ -87,7 +87,7 @@ cd "${ANSIBLE_DIR}" && \
. ./venv/bin/activate && \
pip3 install ansible && \
ansible-playbook ${SKIP_TAGS} --inventory ./hosts ./playbook.yml 2>&1 | tee ${LOG} \
|| die "Error running ansible. journalctl -xe = $(journalctl -xe | tail -n 50) ___dhparams=$(cat /etc/nginx/dhparams.pem)"
|| die "Error running ansible. journalctl -xe = $(journalctl -xe | tail -n 50) ___dhparams=$(if [[ -f /etc/nginx/dhparams.pem ]] ; then cat /etc/nginx/dhparams.pem ; else echo "(does not exist)" ; fi)"

# lockout the node that started us
cat /dev/null > "${AUTH_KEYS}" || die "Error truncating ${AUTH_KEYS} file"


+ 1
- 1
bubble-server/src/main/resources/ansible/roles/bubble/files/bubble_role.json View File

@@ -19,7 +19,7 @@
{"name": "db_name", "value": "bubble"},
{"name": "db_key", "value": "[[dbEncryptionKey]]"},
{"name": "letsencrypt_email", "value": "[[configuration.letsencryptEmail]]"},
{"name": "openapi_contact_email", "value": "openapi_contact_email"},
{"name": "openapi_contact_email", "value": "[[[openapi_contact_email]]]"},
{"name": "is_fork", "value": "[[fork]]"},
{"name": "restore_key", "value": "[[restoreKey]]"},
{"name": "restore_timeout", "value": "[[restoreTimeoutSeconds]]"},


+ 1
- 1
bubble-server/src/main/resources/ansible/roles/bubble/templates/bubble.env.j2 View File

@@ -22,4 +22,4 @@ export APP_LINK_MACOSX={{ app_link_macosx }}
export APP_LINK_LINUX={{ app_link_linux }}

export CERT_VALIDATION_HOST={{ cert_validation_host }}
export OPENAPI_CONTACT_EMAIL={{ openapi_contact_email }}
export OPENAPI_CONTACT_EMAIL={{ openapi_contact_email }}

+ 2
- 1
bubble-server/src/main/resources/ansible/roles/finalizer/files/bubble_role.json View File

@@ -7,7 +7,8 @@
{"name": "install_type", "value": "[[installType]]"},
{"name": "bubble_java_opts", "value": "-XX:MaxRAM=[[jvmMaxRamMB]]m"},
{"name": "total_memory", "value": "[[nodeSize.memoryMB]]"},
{"name": "cert_name", "value": "bubble-[[network.shortId]]"}
{"name": "cert_name", "value": "bubble-[[network.shortId]]"},
{"name": "enable_nginx", "value": "[[bubble_deploy_nginx]]"}
],
"optionalConfigNames": ["restore_key"]
}

+ 9
- 0
bubble-server/src/main/resources/ansible/roles/finalizer/tasks/main.yml View File

@@ -45,21 +45,30 @@

- name: Ensure nginx dhparams.pem file exists and is valid
shell: /usr/local/bin/init_dhparams.sh wait
when: enable_nginx

- name: Ensure nginx required files exist
shell: /usr/local/bin/ensure_file_exists.sh {{ item }} 300
with_items:
- /etc/letsencrypt/live/{{ server_alias }}/fullchain.pem
- /etc/letsencrypt/live/{{ server_name }}/fullchain.pem
when: enable_nginx

- name: Ensure nginx is restarted
service:
name: nginx
state: restarted
when: enable_nginx

- name: stat /usr/share/unattended-upgrades/20auto-upgrades-disabled
stat:
path: /usr/share/unattended-upgrades/20auto-upgrades-disabled
register: upgrades_disabled_file

- name: Enable unattended upgrades
shell: systemctl start unattended-upgrades
become: yes
when: upgrades_disabled_file.stat.exists

- name: Ensure authorized SSH keys are up-to-date
shell: su - bubble bash -c "touch /home/bubble/.refresh_ssh_keys"


+ 2
- 1
bubble-server/src/main/resources/ansible/roles/nginx/files/bubble_role.json View File

@@ -6,6 +6,7 @@
{"name": "letsencrypt_email", "value": "[[configuration.letsencryptEmail]]"},
{"name": "ssl_port", "value": "[[node.sslPort]]"},
{"name": "admin_port", "value": "[[node.adminPort]]"},
{"name": "install_type", "value": "[[installType]]"}
{"name": "install_type", "value": "[[installType]]"},
{"name": "enable_nginx", "value": "[[bubble_deploy_nginx]]"}
]
}

+ 4
- 0
bubble-server/src/main/resources/ansible/roles/nginx/tasks/main.yml View File

@@ -5,13 +5,17 @@
service:
name: nginx
state: stopped
when: enable_nginx

- name: Create dhparam nginx conf
template:
src: stronger_dhparams.conf
dest: /etc/nginx/conf.d/stronger_dhparams.conf
when: enable_nginx

- include: site.yml
when: enable_nginx

- name: Init certbot
shell: init_certbot.sh {{ letsencrypt_email }} {{ server_name }} {{ server_alias }}
when: enable_nginx

+ 0
- 13
bubble-server/src/main/resources/bubble/host-prefixes.txt View File

@@ -3321,7 +3321,6 @@ exude
exuls
exult
exurb
eyass
eyers
eying
eyots
@@ -3348,7 +3347,6 @@ faery
faffs
fagin
faiks
fails
faine
fains
faint
@@ -3369,7 +3367,6 @@ fanga
fango
fangs
fanks
fanny
fanon
fanos
fanum
@@ -3425,7 +3422,6 @@ feces
fecht
fecit
fecks
fedex
feebs
feeds
feels
@@ -3513,7 +3509,6 @@ fifth
fifty
fight
figos
fiked
filar
filed
filer
@@ -3526,9 +3521,7 @@ fills
filly
filmi
films
filmy
filos
filth
filum
final
finca
@@ -3554,10 +3547,8 @@ firns
firry
first
firth
fiscs
fishy
fisks
fists
fisty
fitch
fitly
@@ -3820,7 +3811,6 @@ fuffs
fuffy
fugal
fugle
fugly
fugus
fujis
fulls
@@ -3861,9 +3851,6 @@ fuzee
fuzes
fuzil
fuzzy
fyces
fyked
fykes
fyles
fyrds
fytte


+ 0
- 4
bubble-server/src/main/resources/packer/roles/finalizer/tasks/main.yml View File

@@ -1,10 +1,6 @@
#
# Copyright (c) 2020 Bubble, Inc. All rights reserved. For personal (non-commercial) use, see license: https://getbubblenow.com/bubble-license/
#
- name: Touch first-time setup file
shell: su - bubble bash -c "if [[ ! -f /home/bubble/first_time_marker ]] ; then echo -n install > /home/bubble/first_time_marker ; fi"
when: restore_key is not defined

- name: Install copy_certs_to_bubble.sh helper
copy:
src: copy_certs_to_bubble.sh


+ 1
- 1
utils/cobbzilla-utils

@@ -1 +1 @@
Subproject commit e0faad31cb5cadfc000277d3f2052a57cb441b2d
Subproject commit 72e0962ac1defa342e8bad34044b56ee36817f52

Loading…
Cancel
Save