Skip to content

Commit

Permalink
New development environment.
Browse files Browse the repository at this point in the history
* New vagrant image that works on both Mac M1 and linux amd64.
* Controller assets now run locally in docker, while the vagrant image
  is just the container node for a more simplified environment.
  • Loading branch information
kwatson committed Feb 13, 2024
1 parent bcaaa69 commit a590dfe
Show file tree
Hide file tree
Showing 61 changed files with 686 additions and 508 deletions.
9 changes: 1 addition & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,6 @@ public/tmp
/tmp
.idea/

# Vagrant
#.vagrant/

#vendor/

# Redis
dump.rdb

Expand All @@ -54,7 +49,6 @@ lib/dev/ssl
# Dont commit generated changelog
CHANGELOG.html

.ruby-version
.editorconfig
node_modules
yarn-error.log
Expand Down Expand Up @@ -87,5 +81,4 @@ config/routes/engines.rb
engines/**
!engines/.keep

# Ignore Docker Compose for now...
docker-compose.yml
.consul.token
6 changes: 2 additions & 4 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ workflow:
# CS_MAJOR_VERSION
variables:
FULL_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA-$CI_PIPELINE_ID
DH_IMAGE: cmptstks/controller

default:
tags:
- shell
before_script:
- echo "$CI_REGISTRY_PASSWORD" | docker login $CI_REGISTRY --username $CI_REGISTRY_USER --password-stdin
- echo "$DH_PW" | docker login -u $DH_USER --password-stdin
after_script:
- docker logout $CI_REGISTRY
- docker logout
Expand All @@ -32,8 +30,8 @@ stages:
build:
stage: build
before_script:
- 'docker run -d --rm --name cstacks-pg -e POSTGRES_USER=cstacks -e POSTGRES_DB=cstacks -e POSTGRES_PASSWORD=cstacks postgres:13-alpine'
- 'docker run -d --rm --name cstacks-redis --network "container:cstacks-pg" redis:latest'
- 'docker run -d --rm --name cstacks-pg -e POSTGRES_USER=cstacks -e POSTGRES_DB=cstacks -e POSTGRES_PASSWORD=cstacks postgres:16'
- 'docker run -d --rm --name cstacks-redis --network "container:cstacks-pg" redis:alpine'
after_script:
- docker stop cstacks-redis cstacks-pg
script:
Expand Down
1 change: 1 addition & 0 deletions .node-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20.11.0
6 changes: 5 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ Style/StringLiterals:
Layout/TrailingWhitespace:
Enabled: false
Style/RescueStandardError:
Enabled: false
Enabled: false
Layout/SpaceInsideParens:
Enabled: false
Layout/SpaceInsideArrayLiteralBrackets:
Enabled: false
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.3
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ RUN set -ex; \
git \
supervisor \
nginx-light \
libjemalloc2 \
patchelf \
; \
# Patch Ruby to use jemalloc
patchelf --add-needed libjemalloc.so.2 /usr/local/bin/ruby; \
# Discard patchelf after use
apt-get purge -y \
patchelf \
; \
echo "set_real_ip_from 127.0.0.1;" > /etc/nginx/conf.d/restore_ip.conf \
; \
Expand Down
86 changes: 15 additions & 71 deletions Vagrantfile.sample
Original file line number Diff line number Diff line change
@@ -1,83 +1,27 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

##
# ComputeStacks Vagrantfile
# 1. Copy `envrc.sample` to `.envrc` and update values appropriately.
# * Take note that the `GITHUB_GEM_PULL_TOKEN` is a personal access token with the `read_packages` permission.
# 2. Copy `config/database.sample.yml` to `config/database.yml`.
# * _No changes are required._
# 2. Copy `Vagrantfile.sample` to `Vagrantfile` and make any relevant changes, however it should work out of the box without any modification.
# 3. Bring up with `vagrant up`. This will take a few minutes depending on your computer -- compiling ruby takes a bit.
#
# **Enter the vagrant VM with: `vagrant ssh`**
#
# 4. Install NodeJS & Yarn
# 1. Install nodejs with `nvm install --lts`
# 2. Install yarn `npm -g install yarn`
# 5. `cd ~/controller` and run:
# 1. `direnv allow .`
# 2. `bundle`
# * if you did not setup your `.envrc` correctly, you will get an authorization error. Our provision script will automatically take the credentials in your `.envrc` file and authenticate with Github, but please also reference this document if you run into issues: https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-rubygems-registry
#
# 6. Once all the gems have been installed, bootstrap your database with:
# 1. `bundle exec rails db:create`
# 2. `bundle exec rails db:schema:load`
# 3. `bundle exec rails db:seed`
#
# 7. Bootstrap the controller assets (from inside `~/controller` in vagrant)
# 1. Run `yarn`
# 2. Run `bundle exec rake assets:precompile`
#
# 8. _(optional)_ Install our default CS theme. Skip if you're building your own.
# 1. `mkdir ~/controller/public/assets/custom`
# 2. `wget -q -O ~/controller/public/assets/custom/application.css https://storage.googleapis.com/cstacks/provision_assets/branding/application.css`
# 3. `wget -q -O ~/controller/public/assets/custom/application.css.map https://storage.googleapis.com/cstacks/provision_assets/branding/application.css.map`
# 4. `wget -q -O ~/controller/public/assets/custom/logo-login.png https://storage.googleapis.com/cstacks/provision_assets/branding/logo-login.png`
#
# 9. _(optional)_ Run our test suite with: `bundle exec rails test`
#
# You may now launch ComputeStacks by running `overmind s` from the ~/controller directory within the vagrant vm.
#
# Next, proceed to your browser and visit http://localhost:3005 -- the default credentials are `[email protected]` / `changeme!`
#
# Read `./doc/DEV_SETUP.md`.
Vagrant.configure("2") do |config|

config.vm.synced_folder ".", "/home/vagrant/controller"
config.vm.box = "bento/ubuntu-22.04"
config.vm.synced_folder '.', '/vagrant', disabled: true

# ComputeStacks Web UI: http://localhost:3005
config.vm.network "forwarded_port", guest: 3005, host: 3005, auto_correct: true

# Prometheus: http://localhost:9090
config.vm.network "forwarded_port", guest: 9090, host: 9090, auto_correct: true

# Consul: http://localhost:8500/ui/
config.vm.network "forwarded_port", guest: 8500, host: 8500, auto_correct: true

# ComputeStacks Load Balancer
config.vm.network "forwarded_port", guest: 80, host: 80
config.vm.network "forwarded_port", guest: 443, host: 443

config.vm.box = "bento/debian-12"
config.vm.provider "virtualbox" do |vm|
vm.name = "computestacks"
config.vm.provider :libvirt do |vm|
vm.driver = "kvm"
vm.title = "computestacks"
vm.description = "ComputeStacks Controller"
vm.memory = 4096
vm.cpus = 2
vm.cpus = 4
vm.cputopology sockets: "1", cores: "2", threads: "2"
end

##
# Mac M1/2 with Parallels
#
# config.vm.box = "bento/debian-12-arm64"
# config.vm.provider "parallels" do |vm|
# vm.name = "computestacks"
# vm.memory = 4096
# vm.cpus = 2
# vm.check_guest_tools = true
# vm.update_guest_tools = true
# end
# For use on MacOS M1 with vmware fusion player.
config.vm.provider "vmware_desktop" do |vm|
vm.vmx["memsize"] = "4096"
vm.vmx["numvcpus"] = "4"
end

config.vm.provision "file", source: "lib/test/powerdns/pdns_up.sh", destination: "/tmp/cs_pdns_up"
config.vm.provision "shell", path: "lib/dev/vagrant_provision.sh"
config.vm.provision "shell", path: "lib/dev/vagrant_provision-node.sh"

end
26 changes: 15 additions & 11 deletions app/models/concerns/le_container_domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module LeContainerDomain
def le_active?
return false if system_domain || !le_enabled || !le_ready
return false if lets_encrypt.nil?

lets_encrypt.names.include?(domain) && lets_encrypt.active?
end

Expand All @@ -47,6 +48,7 @@ def le_require_verify?
def le_dns_allowed?(value)
lb = container_service.load_balancer
return nil if lb.nil?

lb.ip_allowed? value
rescue
false
Expand All @@ -58,23 +60,25 @@ def le_dns_allowed?(value)
def lets_encrypt_init!
return true if lets_encrypt
return false unless le_ready

account = LetsEncryptAccount.find_or_create
return false if account.nil?

chosen_cert = nil
chosen_cert = user.lets_encrypts.selectable.first unless Setting.le_single_domain?
chosen_cert = user.lets_encrypts.create!(account: account) if chosen_cert.nil?
if chosen_cert.nil?
SystemEvent.create!(
message: "Unable to generate LetsEncrypt for domain #{domain}",
data: {
domain: {
id: id,
name: domain
},
user: {
id: user.id,
email: user.email
}
domain: {
id: id,
name: domain
},
user: {
id: user.id,
email: user.email
}
},
event_code: "26ed782e7ccfd47b"
)
Expand All @@ -84,9 +88,9 @@ def lets_encrypt_init!
end

def validate_le_domain
if saved_change_to_attribute?("domain") && !skip_validation
LetsEncryptWorkers::ValidateDomainWorker.perform_async(id)
end
return unless saved_change_to_attribute?("domain") && !skip_validation

LetsEncryptWorkers::ValidateDomainWorker.perform_async(id)
end

def disable_le_ready
Expand Down
3 changes: 1 addition & 2 deletions app/models/concerns/nodes/consul_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ def update_iptable_config!(trigger_reload = true)
end

def consul_config
return {} if Rails.env.test? # for test, we dont want any config here!
return {} unless online?
dc = region.name.strip.downcase
{
http_addr: Diplomat.configuration.options.empty? ? "http://#{primary_ip}:8500" : "https://#{primary_ip}:8501",
http_addr: "#{CONSUL_API_PROTO}://#{primary_ip}:#{CONSUL_API_PORT}",
dc: dc.blank? ? nil : dc,
token: region.consul_token
}
Expand Down
3 changes: 1 addition & 2 deletions app/models/concerns/volumes/consul_volume.rb
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,13 @@ def consul_select_node
end

def consul_config
return {} if Rails.env.test? # for test, we dont want any config here!
return {} if nodes.online.empty?
dc = region.nil? ? nodes.online.first.region.name.strip.downcase : region.name.strip.downcase
token = region.nil? ? nodes.online.first.region.consul_token : region.consul_token
return {} if token.blank?
consul_ip = nodes.online.first.primary_ip
{
http_addr: Diplomat.configuration.options.empty? ? "http://#{consul_ip}:8500" : "https://#{consul_ip}:8501",
http_addr: "#{CONSUL_API_PROTO}://#{consul_ip}:#{CONSUL_API_PORT}",
dc: dc.blank? ? nil : dc,
token: token
}
Expand Down
4 changes: 2 additions & 2 deletions app/models/concerns/volumes/volume_driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def destroy_volume!
def volume_client
case volume_backend
when 'nfs'
DockerVolumeNfs.configure ssh_key: ENV['CS_SSH_KEY']
DockerVolumeNfs.configure ssh_key: "#{Rails.root}/#{ENV['CS_SSH_KEY']}"
DockerVolumeNfs::Volume.new self
else
DockerVolumeLocal::Volume.new self
Expand All @@ -29,7 +29,7 @@ def volume_client
def volume_driver_client
case volume_backend
when 'nfs'
DockerVolumeNfs.configure ssh_key: ENV['CS_SSH_KEY']
DockerVolumeNfs.configure ssh_key: "#{Rails.root}/#{ENV['CS_SSH_KEY']}"
DockerVolumeNfs
else
DockerVolumeLocal
Expand Down
2 changes: 1 addition & 1 deletion app/models/container_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ def docker_client
:port_map => ports,
:restart_policy => "always"
}
params = {image_url: "cmptstks/registry:latest", settings: options, node: {key: ENV['CS_SSH_KEY']}}
params = {image_url: "cmptstks/registry:latest", settings: options, node: {key: "#{Rails.root}/#{ENV['CS_SSH_KEY']}"}}
ssh_port = Setting.registry_ssh_port
DockerSSH::Container.new(self.name, "ssh://#{Setting.registry_node}:#{ssh_port}", params)
rescue => e
Expand Down
11 changes: 8 additions & 3 deletions app/models/deployment/container_domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def csrn

def resource_name
return "null" if domain.blank?

domain.strip.downcase.gsub(".","-")[0..10]
end

Expand All @@ -82,6 +83,7 @@ def expected_dns_entries
# expected to be an array
pub = []
return pub if container_service&.load_balancer.nil?

pub << container_service.load_balancer.public_ip
container_service.load_balancer.ipaddrs.where(role: 'public').each do |i|
addr = i.ip_addr.to_s
Expand All @@ -98,9 +100,11 @@ def self.create_system_domain!(service)
sysd = Deployment::ContainerDomain.sys_domain(service.region).first
return [] if sysd.nil?
return [] if service.nil? || service.user.nil?

domains = []
service.ingress_rules.where(external_access: true).each do |ingress|
next if ingress.container_domains.where(system_domain: true).exists?

domains << ingress.container_domains.create!(
domain: "#{service.name}#{ingress.id}.#{sysd}",
system_domain: true,
Expand All @@ -117,6 +121,7 @@ def self.sys_domain(region = nil)
LoadBalancer.all.map { |i| i.domain unless i.domain.blank? }
else
return [] if region.load_balancer.nil?

[region.load_balancer.domain]
end
end
Expand All @@ -125,16 +130,15 @@ def self.sys_domain(region = nil)

def reload_load_balancer!
return true unless ingress_rule

if ingress_rule.external_access
if ingress_rule.load_balancer_rule
# internal load balancer
# @type [Deployment::ContainerService]
lb_service = ingress_rule.load_balancer_rule&.container_service
if lb_service
lb_service.containers.each do |container|
lb_service&.containers&.each do |container|
PowerCycleContainerService.new(container, 'restart', current_audit).perform
end
end
elsif container_service&.load_balancer
LoadBalancerServices::DeployConfigService.new(container_service.load_balancer).perform
end
Expand Down Expand Up @@ -169,6 +173,7 @@ def ensure_ingress_present

def set_primary_domain
return unless make_primary

container_service.update master_domain_id: id
end

Expand Down
Loading

0 comments on commit a590dfe

Please sign in to comment.