├── test ├── node │ ├── express_pg_procfile │ │ ├── src │ │ │ ├── Procfile │ │ │ └── package.json │ │ └── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ ├── express_procfile │ │ ├── src │ │ │ ├── Procfile │ │ │ └── package.json │ │ └── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ ├── express_mongodb_procfile │ │ ├── src │ │ │ ├── Procfile │ │ │ └── package.json │ │ └── expected │ │ │ ├── Dockerfile │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ ├── express_no_git │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── Dockerfile │ │ │ └── service.yml │ │ └── src │ │ │ └── package.json │ ├── express_bare │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ ├── express_rethinkdb │ │ ├── expected │ │ │ ├── Dockerfile │ │ │ └── service.yml │ │ └── src │ │ │ └── package.json │ ├── express_bare_mysql │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ ├── express_mongodb │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ ├── express_bare_mongo │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ ├── express_mongodb_redis │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ ├── express_mysql_pg │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── package.json │ └── Dockerfile.base ├── ruby │ ├── rails_unicorn_mysql │ │ ├── src │ │ │ ├── Procfile │ │ │ ├── config │ │ │ │ └── database.yml │ │ │ └── Gemfile │ │ └── expected │ │ │ ├── Dockerfile │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ ├── rails_jobs_mysql_redis_postgrespl │ │ ├── src │ │ │ ├── Procfile │ │ │ ├── config │ │ │ │ └── database.yml │ │ │ └── Gemfile │ │ └── expected │ │ │ ├── Dockerfile │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ ├── rails_mysql │ │ ├── src │ │ │ ├── Procfile │ │ │ ├── source.zip │ │ │ ├── Gemfile │ │ │ └── config │ │ │ │ └── database.yml │ │ └── expected │ │ │ ├── Dockerfile │ │ │ ├── api │ │ │ ├── Dockerfile │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ ├── rails_jobs_unicorn_redis_postgresql │ │ ├── src │ │ │ ├── Procfile │ │ │ ├── Gemfile │ │ │ └── config │ │ │ │ └── database.yml │ │ └── expected │ │ │ ├── Dockerfile │ │ │ ├── docker-compose.yml │ │ │ └── service.yml │ ├── Dockerfile.base │ └── sinatra_mongo │ │ ├── expected │ │ ├── Dockerfile │ │ ├── docker-compose.yml │ │ └── service.yml │ │ └── src │ │ └── Gemfile ├── docker_compose │ ├── just_compose_2 │ │ ├── src │ │ │ ├── env.env │ │ │ ├── settings.env │ │ │ └── docker-compose.yml │ │ └── expected │ │ │ └── service.yml │ └── just_compose │ │ ├── expected │ │ └── service.yml │ │ └── src │ │ └── docker-compose.yml ├── php │ ├── laravel_bare_mysql │ │ ├── expected │ │ │ ├── docker-compose.yml │ │ │ ├── service.yml │ │ │ └── Dockerfile │ │ └── src │ │ │ └── composer.json │ └── Dockerfile.base └── service_yml │ ├── service_to_kubes_1 │ ├── src │ │ └── service.yml │ └── expected │ │ └── kubernetes.yml │ └── service_to_kubes_2 │ └── src │ └── service.yml ├── definitions ├── docker-compose │ ├── dns.go │ ├── tmpfs.go │ ├── command.go │ ├── env-file.go │ ├── DnsSearch.go │ ├── entrypoint.go │ ├── environment.go │ ├── limits.go │ ├── placement.go │ ├── ulimits.go │ ├── aliases.go │ ├── update-config.go │ ├── networks.go │ ├── cpus-mem.go │ ├── logging.go │ ├── resources.go │ ├── healthcheck.go │ ├── restart-policy.go │ ├── port.go │ ├── volumes.go │ ├── secrets.go │ ├── deploy.go │ ├── build.go │ ├── docker-compose-base.go │ ├── service.go │ └── utils.go ├── service-yml │ ├── traffic-matches.go │ ├── constraints.go │ ├── service-yml-resources.go │ ├── port.go │ ├── service-yml-base.go │ ├── custom-yaml-unmarsahler.go │ ├── service.go │ └── utils.go ├── kubernetes │ ├── handler.go │ ├── exec.go │ ├── resources.go │ ├── security-context.go │ ├── limits.go │ ├── env-vars.go │ ├── template.go │ ├── lifecycle.go │ ├── metadata.go │ ├── volume-mounts.go │ ├── service.go │ ├── deployment.go │ ├── ports.go │ ├── spec.go │ ├── containers.go │ ├── kubernetes-base.go │ └── utils.go └── definition-interface.go ├── publish.sh ├── common ├── database.go ├── env-var.go ├── service.go ├── port-mapping.go ├── lister.go ├── utils-php.go ├── utils-python.go ├── utils-ruby.go ├── utils-git.go └── utils-template.go ├── packs ├── detector-interface.go ├── pack-element.go ├── node │ ├── dockerfile-writer.go │ ├── dockerfile-context.go │ ├── service-yaml-context.go │ ├── service-yaml-writer.go │ ├── docker-compose-yaml-context.go │ ├── docker-compose-yaml-writer.go │ ├── analysis.go │ └── detector.go ├── php │ ├── dockerfile-context.go │ ├── dockerfile-writer.go │ ├── service-yaml-writer.go │ ├── service-yaml-context.go │ ├── docker-compose-yaml-writer.go │ ├── docker-compose-yaml-context.go │ ├── analysis.go │ ├── detector.go │ ├── analyzer.go │ └── pack.go ├── ruby │ ├── dockerfile-writer.go │ ├── dockerfile-context.go │ ├── service-yaml-context.go │ ├── service-yaml-writer.go │ ├── docker-compose-yaml-context.go │ ├── docker-compose-yaml-writer.go │ ├── analysis.go │ ├── detector.go │ └── webservers │ │ ├── thin.go │ │ └── unicorn.go ├── python │ ├── dockerfile-writer.go │ ├── service-yaml-context.go │ ├── service-yaml-writer.go │ ├── dockerfile-context.go │ ├── analysis.go │ ├── detector.go │ ├── webservers │ │ └── gunicorn.go │ └── pack.go ├── docker-compose-yaml-context-base.go ├── analyzer-interface.go ├── web-server-interface.go ├── dockerfile-context-base.go ├── service-yml-to-kubes │ ├── analysis.go │ ├── detector.go │ ├── analyzer.go │ └── pack.go ├── compose-to-service-yml │ ├── analysis.go │ ├── detector.go │ ├── analyzer.go │ └── pack.go ├── dockerfile-writer-base.go ├── analysis-base.go ├── pack-base.go ├── web-server-base.go ├── docker-compose-yaml-writer-base.go ├── pack-interface.go ├── service-yaml-context-base.go ├── service-yaml-writer-base.go └── template-writer-base.go ├── bundle ├── templates │ ├── modifier.go │ ├── template-interface.go │ ├── templates.go │ ├── template.go │ ├── workflow.go │ ├── policy.go │ ├── filter.go │ ├── transformation.go │ ├── helm-release.go │ └── stencil.go └── bundles │ ├── workflow.go │ ├── filter.go │ ├── metadata.go │ ├── base-template.go │ ├── policy.go │ ├── tranformation.go │ ├── helm-release.go │ ├── stencil.go │ └── bundle.go ├── utils ├── version.go └── update.go ├── docker-compose.yml ├── service.yml ├── compile.sh ├── templates ├── python.dockerfile.template ├── docker-compose.yml.template ├── ruby.dockerfile.template ├── service.yml.template ├── templates.json ├── php.dockerfile.template └── node.dockerfile.template ├── Dockerfile.production ├── cloudbuild.json ├── transform ├── transformer-interface.go └── kubes-transformer.go ├── Dockerfile.crosscompile ├── .gitignore ├── Dockerfile ├── config.go ├── go.mod ├── starter_suite_test.go ├── CHANGELOG.md ├── cli_test.go └── detect.go /test/node/express_pg_procfile/src/Procfile: -------------------------------------------------------------------------------- 1 | web: $WEB 2 | -------------------------------------------------------------------------------- /test/node/express_procfile/src/Procfile: -------------------------------------------------------------------------------- 1 | express: node server.js 2 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/src/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec unicorn -p $PORT -v 2 | -------------------------------------------------------------------------------- /definitions/docker-compose/dns.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Dns []string 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/tmpfs.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Tmpfs []string 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/command.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Command []string 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/env-file.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type EnvFile []string 4 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/src/Procfile: -------------------------------------------------------------------------------- 1 | worker: bundle exec rake jobs:work 2 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/src/Procfile: -------------------------------------------------------------------------------- 1 | custom_web: bundle exec rails s -p 3000 -E $RAILS_ENV -D 2 | -------------------------------------------------------------------------------- /definitions/docker-compose/DnsSearch.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type DnsSearch []string 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/entrypoint.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Entrypoint []string 4 | -------------------------------------------------------------------------------- /definitions/service-yml/traffic-matches.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | type TrafficMatches []string 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/environment.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Environment map[string]string 4 | -------------------------------------------------------------------------------- /publish.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | aws s3 cp build s3://downloads.cloud66.com/starter --acl public-read --recursive -------------------------------------------------------------------------------- /test/node/express_mongodb_procfile/src/Procfile: -------------------------------------------------------------------------------- 1 | web: node lib/index.js 2 | background: node lib/background.js 3 | -------------------------------------------------------------------------------- /common/database.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type Database struct { 4 | Name string 5 | DockerImage string 6 | } 7 | -------------------------------------------------------------------------------- /definitions/docker-compose/limits.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Limits struct { 4 | Soft int 5 | Hard int 6 | } 7 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/src/source.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cloud66-oss/starter/HEAD/test/ruby/rails_mysql/src/source.zip -------------------------------------------------------------------------------- /definitions/docker-compose/placement.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Placement struct { 4 | Constraints []string 5 | } 6 | -------------------------------------------------------------------------------- /definitions/kubernetes/handler.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Handler struct { 4 | Exec Exec `yaml:"exec,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /definitions/kubernetes/exec.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Exec struct { 4 | Command []string `yaml:"command,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /definitions/docker-compose/ulimits.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Ulimits struct { 4 | Nproc Limits 5 | Nofile Limits 6 | } 7 | -------------------------------------------------------------------------------- /definitions/kubernetes/resources.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Resources struct { 4 | Limits Limits `yaml:"limits,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /packs/detector-interface.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | type Detector interface { 4 | GetPack() Pack 5 | Detect(rootDir string) bool 6 | } 7 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose_2/src/env.env: -------------------------------------------------------------------------------- 1 | # Set Rails/Rack environment 2 | RACK_ENV=Env_var_from_file 3 | RACK2=a second env var from file 4 | -------------------------------------------------------------------------------- /definitions/docker-compose/aliases.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Aliases struct { 4 | Aliases []string `yaml:"aliases,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /definitions/docker-compose/update-config.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type UpdateConfig struct { 4 | Parallelism int 5 | Delay string 6 | } 7 | -------------------------------------------------------------------------------- /definitions/service-yml/constraints.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | type Constraints struct { 4 | Resources Resources `yaml:"resources,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose_2/src/settings.env: -------------------------------------------------------------------------------- 1 | 2 | NODE_ENV=${NODE_ENV} 3 | PORT=${PORT} 4 | VIRTUAL_HOST=${VIRTUAL_HOST} 5 | VIRTUAL_PORT=${PORT} 6 | -------------------------------------------------------------------------------- /bundle/templates/modifier.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Modifier struct { 4 | Type string `json:"type"` 5 | Filename string `json:"filename"` 6 | } 7 | -------------------------------------------------------------------------------- /definitions/kubernetes/security-context.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type SecurityContext struct { 4 | Priviliged bool `yaml:"priviliged,omitempty"` 5 | } 6 | -------------------------------------------------------------------------------- /bundle/templates/template-interface.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type TemplateInterface interface { 4 | GetName() string 5 | GetDependencies() []string 6 | } 7 | -------------------------------------------------------------------------------- /definitions/docker-compose/networks.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Networks struct { 4 | ShortSyntax []string 5 | Aliases map[string]Aliases 6 | } 7 | -------------------------------------------------------------------------------- /definitions/definition-interface.go: -------------------------------------------------------------------------------- 1 | package definitions 2 | 3 | type Definition interface { 4 | UnmarshalFromFile(path string) 5 | MarshalToFile(path string) 6 | } 7 | -------------------------------------------------------------------------------- /utils/version.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | var ( 4 | // Version is starter version 5 | Version = "1.4.2" 6 | // Channel is the build channel 7 | Channel = "dev" 8 | ) 9 | -------------------------------------------------------------------------------- /definitions/kubernetes/limits.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Limits struct { 4 | Cpu int `yaml:"cpu,omitempty"` 5 | Memory string `yaml:"memory,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/pack-element.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | type PackElement struct { 4 | Pack Pack 5 | } 6 | 7 | func (e *PackElement) GetPack() Pack { 8 | return e.Pack 9 | } 10 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/src/Procfile: -------------------------------------------------------------------------------- 1 | custom_web: bundle exec unicorn_rails -c config/unicorn.rb -E $RAILS_ENV $DAEMONIZE 2 | worker: bundle exec sidekiq 3 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | starter: 2 | dockerfile: Dockerfile 3 | build: . 4 | volumes: 5 | - ${PWD}:/usr/local/go/src/github.com/cloud66/starter 6 | ports: 7 | - 9091:9090 -------------------------------------------------------------------------------- /packs/node/dockerfile-writer.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileWriter struct { 6 | packs.DockerfileWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/php/dockerfile-context.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileContext struct { 6 | packs.DockerfileContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/php/dockerfile-writer.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileWriter struct { 6 | packs.DockerfileWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/php/service-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLWriter struct { 6 | packs.ServiceYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/dockerfile-writer.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileWriter struct { 6 | packs.DockerfileWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /definitions/kubernetes/env-vars.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type EnvVar struct { 4 | Name interface{} `yaml:"name,omitempty"` 5 | Value interface{} `yaml:"value,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/node/dockerfile-context.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileContext struct { 6 | packs.DockerfileContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/node/service-yaml-context.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLContext struct { 6 | packs.ServiceYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/node/service-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLWriter struct { 6 | packs.ServiceYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/php/service-yaml-context.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLContext struct { 6 | packs.ServiceYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/python/dockerfile-writer.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileWriter struct { 6 | packs.DockerfileWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/dockerfile-context.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileContext struct { 6 | packs.DockerfileContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/service-yaml-context.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLContext struct { 6 | packs.ServiceYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/service-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLWriter struct { 6 | packs.ServiceYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /definitions/docker-compose/cpus-mem.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type CpusMem struct { 4 | Cpus string `yaml:"cpus,omitempty"` 5 | Memory string `yaml:"memory,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /definitions/kubernetes/template.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Template struct { 4 | Metadata Metadata `yaml:"metadata,omitempty"` 5 | PodSpec PodSpec `yaml:"spec,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/python/service-yaml-context.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLContext struct { 6 | packs.ServiceYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/python/service-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type ServiceYAMLWriter struct { 6 | packs.ServiceYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /definitions/service-yml/service-yml-resources.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | type Resources struct { 4 | Memory string `yaml:"memory,omitempty"` 5 | Cpu int `yaml:"cpu,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /definitions/kubernetes/lifecycle.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Lifecycle struct { 4 | PostStart Handler `yaml:"postStart,omitempty"` 5 | PreStop Handler `yaml:"preStop,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/php/docker-compose-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLWriter struct { 6 | packs.DockerComposeYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /definitions/kubernetes/metadata.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Metadata struct { 4 | Name string `yaml:"name,omitempty"` 5 | Labels map[string]string `yaml:"labels,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/node/docker-compose-yaml-context.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLContext struct { 6 | packs.DockerComposeYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/node/docker-compose-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLWriter struct { 6 | packs.DockerComposeYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/php/docker-compose-yaml-context.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLContext struct { 6 | packs.DockerComposeYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/docker-compose-yaml-context.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLContext struct { 6 | packs.DockerComposeYAMLContextBase 7 | } 8 | -------------------------------------------------------------------------------- /packs/ruby/docker-compose-yaml-writer.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerComposeYAMLWriter struct { 6 | packs.DockerComposeYAMLWriterBase 7 | } 8 | -------------------------------------------------------------------------------- /test/node/express_no_git/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_no_git/src/ 5 | command: node index.js 6 | ports: 7 | - "3000:3000" -------------------------------------------------------------------------------- /definitions/docker-compose/logging.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Logging struct { 4 | Driver string `yaml:"driver,omitempty"` 5 | Options map[string]string `yaml:"options,omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /definitions/docker-compose/resources.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Resources struct { 4 | Limits CpusMem `yaml:"limits,omitempty"` 5 | Reservations CpusMem `yaml:reservations",omitempty"` 6 | } 7 | -------------------------------------------------------------------------------- /packs/python/dockerfile-context.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type DockerfileContext struct { 6 | packs.DockerfileContextBase 7 | RequirementsTxt string 8 | } 9 | -------------------------------------------------------------------------------- /definitions/docker-compose/healthcheck.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Healthcheck struct { 4 | Test []string 5 | Interval string 6 | Timeout string 7 | Retries string 8 | Disable bool 9 | } 10 | -------------------------------------------------------------------------------- /bundle/bundles/workflow.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Workflow struct { 4 | Uid string `json:"uid"` 5 | Name string `json:"name"` 6 | Default bool `json:"default"` 7 | Tags []string `json:"tags"` 8 | } 9 | -------------------------------------------------------------------------------- /common/env-var.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type EnvVar struct { 4 | Key string 5 | Value string 6 | } 7 | 8 | func NewEnvMapping(key string, value string) *EnvVar { 9 | return &EnvVar{Key: key, Value: value} 10 | } 11 | -------------------------------------------------------------------------------- /packs/docker-compose-yaml-context-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | type DockerComposeYAMLContextBase struct { 6 | Services []*common.Service 7 | Dbs []common.Database 8 | } 9 | -------------------------------------------------------------------------------- /test/node/express_procfile/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example-nodejs-express", 3 | "version": "0.0.3", 4 | "engines": { 5 | "node": "4.2.x" 6 | }, 7 | "dependencies": { 8 | "express": "4.13.x" 9 | } 10 | } -------------------------------------------------------------------------------- /test/node/express_bare/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_bare/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | environment: 9 | - PORT=3000 10 | -------------------------------------------------------------------------------- /bundle/bundles/filter.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Filter struct { 4 | Name string `json:"name"` 5 | Description string `json:"description"` 6 | Filename string `json:"filename"` 7 | Tags []string `json:"tags"` 8 | } 9 | -------------------------------------------------------------------------------- /bundle/bundles/metadata.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | import "time" 4 | 5 | type Metadata struct { 6 | App string `json:"app"` 7 | Timestamp time.Time `json:"timestamp"` 8 | Annotations []string `json:"annotations"` 9 | } 10 | -------------------------------------------------------------------------------- /definitions/kubernetes/volume-mounts.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type VolumeMounts struct { 4 | MountPath string `yaml:"mountPath,omitempty"` 5 | Name string `yaml:"name,omitempty"` 6 | ReadOnly bool `yaml:"readOnly,omitempty"` 7 | } 8 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/src/config/database.yml: -------------------------------------------------------------------------------- 1 | development: 2 | adapter: mysql2 3 | database: base_service_development 4 | encoding: utf8 5 | test: 6 | adapter: mysql2 7 | database: base_service_test 8 | encoding: utf8 9 | -------------------------------------------------------------------------------- /bundle/bundles/base-template.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type BaseTemplate struct { 4 | Name string `json:"name"` 5 | Repo string `json:"repo"` 6 | Branch string `json:"branch"` 7 | Stencils []*Stencil `json:"stencils"` 8 | } 9 | -------------------------------------------------------------------------------- /packs/analyzer-interface.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | type Analyzer interface { 6 | FillServices(*[]*common.Service) error 7 | HasPackage(pack string) bool 8 | GuessFramework() string 9 | } 10 | -------------------------------------------------------------------------------- /packs/python/analysis.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext 10 | } 11 | -------------------------------------------------------------------------------- /test/node/express_procfile/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | express: 4 | build: test/node/express_procfile/src/ 5 | command: node server.js 6 | ports: 7 | - "3001:3001" 8 | environment: 9 | - PORT=3001 10 | -------------------------------------------------------------------------------- /test/node/express_no_git/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM node:latest 3 | 4 | ENV APP_HOME /app 5 | RUN mkdir -pv $APP_HOME 6 | WORKDIR $APP_HOME 7 | 8 | ADD package.json $APP_HOME/ 9 | RUN npm install 10 | 11 | ADD . $APP_HOME 12 | -------------------------------------------------------------------------------- /test/node/express_rethinkdb/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM node:6.6.0 3 | 4 | ENV APP_HOME /app 5 | RUN mkdir -pv $APP_HOME 6 | WORKDIR $APP_HOME 7 | 8 | ADD package.json $APP_HOME/ 9 | RUN npm install 10 | 11 | ADD . $APP_HOME 12 | -------------------------------------------------------------------------------- /bundle/bundles/policy.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Policy struct { 4 | UID string `json:"uid"` 5 | Name string `json:"name"` 6 | Filename string `json:"filename"` 7 | Sequence int `json:"sequence"` 8 | Tags []string `json:"tags"` 9 | } 10 | -------------------------------------------------------------------------------- /packs/web-server-interface.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | type WebServer interface { 4 | Names() []string 5 | Port(command *string) string 6 | ParsePort(command string) (hasFound bool, port string) 7 | RemovePortIfEnvVar(command string) string 8 | DefaultPort() string 9 | } 10 | -------------------------------------------------------------------------------- /service.yml: -------------------------------------------------------------------------------- 1 | --- 2 | services: 3 | starter: 4 | git_url: http://github.com/cloud66/starter.git 5 | git_branch: master 6 | use_habitus: true 7 | use_habitus_step: runtime 8 | ports: 9 | - container: 9090 10 | http: 80 11 | https: 443 12 | -------------------------------------------------------------------------------- /packs/dockerfile-context-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | type DockerfileContextBase struct { 6 | Version string 7 | Framework string 8 | Packages *common.Lister 9 | FrameworkVersion string 10 | } 11 | -------------------------------------------------------------------------------- /test/ruby/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM ruby:latest 2 | 3 | RUN apt-get update -qq && apt-get install -y build-essential nodejs 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD Gemfile* $APP_HOME/ 10 | RUN bundle install 11 | 12 | ADD . $APP_HOME 13 | -------------------------------------------------------------------------------- /bundle/bundles/tranformation.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Transformation struct { 4 | UID string `json:"uid"` 5 | Name string `json:"name"` 6 | Filename string `json:"filename"` 7 | Sequence int `json:"sequence"` 8 | Tags []string `json:"tags"` 9 | } 10 | -------------------------------------------------------------------------------- /definitions/kubernetes/service.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type KubesService struct { 4 | ApiVersion string `yaml:"apiVersion,omitempty"` 5 | Kind string `yaml:"kind,omitempty"` 6 | Metadata Metadata `yaml:"metadata,omitempty"` 7 | Spec Spec `yaml:"spec,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /definitions/kubernetes/deployment.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type KubesDeployment struct { 4 | ApiVersion string `yaml:"apiVersion,omitempty"` 5 | Kind string `yaml:"kind,omitempty"` 6 | Metadata Metadata `yaml:"metadata,omitempty"` 7 | Spec Spec `yaml:"spec,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /definitions/docker-compose/restart-policy.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type RestartPolicy struct { 4 | Condition string `yaml:"condition,omitempty"` 5 | Delay string `yaml:"delay,omitempty"` 6 | MaxAttempts int `yaml:"max_attempts,omitempty"` 7 | Window string `yaml:"window,omitempty"` 8 | } 9 | -------------------------------------------------------------------------------- /packs/node/analysis.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | DockerComposeYAMLContext *DockerComposeYAMLContext 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext 10 | } 11 | -------------------------------------------------------------------------------- /packs/php/analysis.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | DockerComposeYAMLContext *DockerComposeYAMLContext 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext 10 | } 11 | -------------------------------------------------------------------------------- /packs/ruby/analysis.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | DockerComposeYAMLContext *DockerComposeYAMLContext 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext 10 | } 11 | -------------------------------------------------------------------------------- /test/php/laravel_bare_mysql/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/php/laravel_bare_mysql/src/ 5 | command: apache2-foreground 6 | ports: 7 | - "3000:80" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | mysql: 12 | image: mysql 13 | -------------------------------------------------------------------------------- /definitions/docker-compose/port.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Ports []Port 4 | 5 | type Port struct { 6 | Target int `yaml:"target,omitempty"` 7 | Published int `yaml:"published,omitempty"` 8 | Protocol string `yaml:"protocol,omitempty"` 9 | Mode string `yaml:"mode,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /definitions/docker-compose/volumes.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Volumes []Volume 4 | 5 | type Volume struct { 6 | Type string `yaml:"type,omitempty"` 7 | Source string `yaml:"source,omitempty"` 8 | Target string `yaml:"target,omitempty"` 9 | ReadOnly bool `yaml:"read_only,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /test/node/express_bare/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example_nodejs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "server.js", 6 | "scripts": { 7 | "start": "node server.js" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.13.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:2.1.2 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /packs/service-yml-to-kubes/analysis.go: -------------------------------------------------------------------------------- 1 | package service_yml_to_kubes 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | /*DockerComposeYAMLContext *DockerComposeYAMLContext 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext*/ 10 | } 11 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/api/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:2.1.2 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /test/ruby/sinatra_mongo/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:latest 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /packs/compose-to-service-yml/analysis.go: -------------------------------------------------------------------------------- 1 | package compose_to_service_yml 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Analysis struct { 6 | packs.AnalysisBase 7 | /*DockerComposeYAMLContext *DockerComposeYAMLContext 8 | ServiceYAMLContext *ServiceYAMLContext 9 | DockerfileContext *DockerfileContext*/ 10 | } 11 | -------------------------------------------------------------------------------- /test/node/express_bare_mysql/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_bare_mysql/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | environment: 12 | - PORT=3000 13 | mysql: 14 | image: mysql 15 | -------------------------------------------------------------------------------- /test/node/express_mongodb/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_mongodb/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mongodb 10 | - mongodb:mongodb.cloud66.local 11 | environment: 12 | - PORT=3000 13 | mongodb: 14 | image: mongo 15 | -------------------------------------------------------------------------------- /definitions/docker-compose/secrets.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Secrets []Secret 4 | 5 | type Secret struct { 6 | Source string `yaml:"source,omitempty"` 7 | Target string `yaml:"target,omitempty"` 8 | Uid string `yaml:"uid,omitempty"` 9 | Gid string `yaml:"gid,omitempty"` 10 | Mode string `yaml:"mode,omitempty"` 11 | } 12 | -------------------------------------------------------------------------------- /test/node/express_no_git/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: no_git_found 7 | git_branch: no_git_found 8 | command: node index.js 9 | build_root: test/node/express_no_git/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | -------------------------------------------------------------------------------- /test/node/express_bare_mongo/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_bare_mongo/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mongodb 10 | - mongodb:mongodb.cloud66.local 11 | environment: 12 | - PORT=3000 13 | mongodb: 14 | image: mongo 15 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:latest 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /test/node/express_no_git/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example_nodejs", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.13.4" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /bundle/bundles/helm-release.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type HelmRelease struct { 4 | UID string `json:"uid"` 5 | ChartName string `json:"chart_name"` 6 | DisplayName string `json:"display_name"` 7 | Version string `json:"version"` 8 | RepositoryURL string `json:"repository_url"` 9 | ValuesFile string `json:"values_file"` 10 | } 11 | -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | gox -ldflags "-X main.BUILDDATE=`date -u '+%Y-%m-%d'` -X main.VERSION=1.3.2" -osarch="darwin/386 darwin/amd64 linux/386 linux/amd64 windows/386 windows/amd64" -output="compiled/{{.Dir}}_{{.OS}}_{{.Arch}}" 3 | CGO_ENABLED=0 gox -ldflags "-X main.BUILDDATE=`date -u '+%Y-%m-%d'` -X main.VERSION=1.3.2" -osarch="linux/amd64" -output="compiled/starter" 4 | -------------------------------------------------------------------------------- /templates/python.dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM python:{{.Version}} 2 | 3 | RUN apt-get update -qq && apt-get install -y build-essential {{.Packages.ToList " "}} 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD {{.RequirementsTxt}} $APP_HOME/ 10 | RUN pip install --no-cache-dir -r {{.RequirementsTxt}} 11 | 12 | ADD . $APP_HOME 13 | 14 | -------------------------------------------------------------------------------- /test/node/express_pg_procfile/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_pg_procfile/src/ 5 | command: _env:WEB 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - postgresql 10 | - postgresql:postgresql.cloud66.local 11 | environment: 12 | - PORT=3000 13 | postgresql: 14 | image: postgres 15 | -------------------------------------------------------------------------------- /test/node/express_procfile/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | express: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: node server.js 9 | build_root: test/node/express_procfile/src/ 10 | ports: 11 | - container: 3001 12 | env_vars: 13 | PORT: 3001 14 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:2.2.2 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs imagemagick libmagickwand-dev 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /packs/ruby/detector.go: -------------------------------------------------------------------------------- 1 | package ruby 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Detector struct { 11 | packs.PackElement 12 | } 13 | 14 | func (d *Detector) Detect(rootDir string) bool { 15 | return common.FileExists(filepath.Join(rootDir, "Gemfile")) 16 | } 17 | -------------------------------------------------------------------------------- /common/service.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type Service struct { 4 | Name string 5 | GitRepo string 6 | GitBranch string 7 | Command string 8 | BuildCommand string 9 | DeployCommand string 10 | Tags []string 11 | Ports []*PortMapping 12 | EnvVars []*EnvVar 13 | BuildRoot string 14 | Databases []Database 15 | } 16 | -------------------------------------------------------------------------------- /packs/php/detector.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Detector struct { 11 | packs.PackElement 12 | } 13 | 14 | func (d *Detector) Detect(rootDir string) bool { 15 | return common.FileExists(filepath.Join(rootDir, "composer.json")) 16 | } 17 | -------------------------------------------------------------------------------- /packs/python/detector.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Detector struct { 11 | packs.PackElement 12 | } 13 | 14 | func (d *Detector) Detect(rootDir string) bool { 15 | return common.FileExists(filepath.Join(rootDir, "requirements.txt")) 16 | } 17 | -------------------------------------------------------------------------------- /packs/dockerfile-writer-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "fmt" 4 | 5 | type DockerfileWriterBase struct { 6 | PackElement 7 | TemplateWriterBase 8 | } 9 | 10 | func (w *DockerfileWriterBase) Write(context interface{}) error { 11 | templateName := fmt.Sprintf("%s.dockerfile.template", w.GetPack().Name()) 12 | return w.WriteTemplate(templateName, "Dockerfile", context) 13 | } 14 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM ruby:latest 3 | 4 | RUN apt-get update -qq && apt-get install -y build-essential nodejs imagemagick libmagickwand-dev memcached 5 | 6 | ENV APP_HOME /app 7 | RUN mkdir $APP_HOME 8 | WORKDIR $APP_HOME 9 | 10 | ADD Gemfile* $APP_HOME/ 11 | RUN bundle install 12 | 13 | ADD . $APP_HOME 14 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | custom_web: 4 | build: . 5 | command: bundle exec rails s -p 3000 -E _env:RAILS_ENV -D 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | environment: 12 | - RAILS_ENV=production 13 | - RACK_ENV=production 14 | mysql: 15 | image: mysql 16 | -------------------------------------------------------------------------------- /test/node/express_bare/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_bare/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/ruby/rails_unicorn_mysql/src/ 5 | command: bundle exec unicorn -v 6 | ports: 7 | - "8080:8080" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | environment: 12 | - RAILS_ENV=production 13 | - RACK_ENV=production 14 | mysql: 15 | image: mysql 16 | -------------------------------------------------------------------------------- /Dockerfile.production: -------------------------------------------------------------------------------- 1 | # use the alpine base image 2 | FROM alpine:3.6 3 | MAINTAINER Cloud 66 4 | 5 | RUN apk --update upgrade && apk add curl ca-certificates && rm -rf /var/cache/apk/* 6 | 7 | RUN mkdir -p /app 8 | WORKDIR /app 9 | 10 | # copy the binary 11 | COPY ./artifacts/compiled/starter /app 12 | COPY ./templates /app/templates 13 | CMD /app/starter -daemon -templates templates -registry true 14 | -------------------------------------------------------------------------------- /definitions/kubernetes/ports.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Port struct { 4 | Name string `yaml:"name,omitempty"` 5 | Port int `yaml:"port,omitempty"` 6 | Protocol string `yaml:"protocol,omitempty"` 7 | TargetPort int `yaml:"targetPort,omitempty"` 8 | ContainerPort int `yaml:"containerPort,omitempty"` 9 | NodePort int `yaml:"nodePort,omitempty"` 10 | } 11 | -------------------------------------------------------------------------------- /packs/service-yml-to-kubes/detector.go: -------------------------------------------------------------------------------- 1 | package service_yml_to_kubes 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Detector struct { 11 | packs.PackElement 12 | } 13 | 14 | func (d *Detector) Detect(rootDir string) bool { 15 | return common.FileExists(filepath.Join(rootDir, "service.yml")) 16 | } 17 | -------------------------------------------------------------------------------- /packs/compose-to-service-yml/detector.go: -------------------------------------------------------------------------------- 1 | package compose_to_service_yml 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | "github.com/cloud66-oss/starter/packs" 6 | "path/filepath" 7 | ) 8 | 9 | type Detector struct { 10 | packs.PackElement 11 | } 12 | 13 | func (d *Detector) Detect(rootDir string) bool { 14 | return common.FileExists(filepath.Join(rootDir, "docker-compose.yml")) 15 | } 16 | -------------------------------------------------------------------------------- /test/php/laravel_bare_mysql/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: apache2-foreground 9 | build_root: test/php/laravel_bare_mysql/src/ 10 | ports: 11 | - container: 80 12 | http: 80 13 | https: 443 14 | 15 | databases: 16 | - mysql 17 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | custom_web: 4 | build: test/ruby/rails_mysql/src/ 5 | command: bundle exec rails s -p 3000 -E _env:RAILS_ENV -D 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | environment: 12 | - RAILS_ENV=production 13 | - RACK_ENV=production 14 | mysql: 15 | image: mysql 16 | -------------------------------------------------------------------------------- /bundle/bundles/stencil.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Stencil struct { 4 | UID string `json:"uid"` 5 | Filename string `json:"filename"` 6 | TemplateFilename string `json:"template_filename"` 7 | ContextID string `json:"context_id"` 8 | Status int `json:"status"` 9 | Tags []string `json:"tags"` 10 | Sequence int `json:"sequence"` 11 | } 12 | -------------------------------------------------------------------------------- /common/port-mapping.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | type PortMapping struct { 4 | Container string 5 | HTTP string 6 | HTTPS string 7 | TCP string 8 | UDP string 9 | } 10 | 11 | func NewPortMapping() *PortMapping { 12 | return &PortMapping{HTTP: "80", HTTPS: "443"} 13 | } 14 | 15 | func NewInternalPortMapping(container string) *PortMapping { 16 | return &PortMapping{Container: container} 17 | } 18 | -------------------------------------------------------------------------------- /cloudbuild.json: -------------------------------------------------------------------------------- 1 | { 2 | "steps": [ 3 | { 4 | "name": "gcr.io/kaniko-project/executor:latest", 5 | "args": [ 6 | "--destination=us-east4-docker.pkg.dev/production-911/docker-private/starter:$SHORT_SHA", 7 | "--build-arg=SHORT_SHA=$SHORT_SHA", 8 | "--cache=true", 9 | "--cache-ttl=5h" 10 | ] 11 | } 12 | ], 13 | "timeout": "1200s" 14 | } 15 | -------------------------------------------------------------------------------- /packs/ruby/webservers/thin.go: -------------------------------------------------------------------------------- 1 | package webservers 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Thin struct { 6 | packs.WebServerBase 7 | } 8 | 9 | func (t *Thin) Names() []string { 10 | return []string{"thin"} 11 | } 12 | 13 | func (t *Thin) Port(command *string) string { 14 | return t.WebServerBase.Port(t, command) 15 | } 16 | 17 | func (t *Thin) DefaultPort() string { 18 | return "3000" 19 | } 20 | -------------------------------------------------------------------------------- /bundle/templates/templates.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Templates struct { 4 | Stencils []*Stencil `json:"stencils"` 5 | Policies []*Policy `json:"policies"` 6 | Transformations []*Transformation `json:"transformations"` 7 | HelmCharts []*HelmRelease `json:"helm_charts"` 8 | Workflows []*Workflow `json:"workflows"` 9 | Filters []*Filter `json:"filters"` 10 | } 11 | -------------------------------------------------------------------------------- /test/node/express_mongodb_redis/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_mongodb_redis/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mongodb 10 | - mongodb:mongodb.cloud66.local 11 | - redis 12 | - redis:redis.cloud66.local 13 | environment: 14 | - PORT=3000 15 | mongodb: 16 | image: mongo 17 | redis: 18 | image: redis 19 | -------------------------------------------------------------------------------- /definitions/kubernetes/spec.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Spec struct { 4 | Ports []Port `yaml:"ports,omitempty"` 5 | Template Template `yaml:"template,omitempty"` 6 | Type string `yaml:"type,omitempty"` 7 | } 8 | 9 | type PodSpec struct { 10 | Containers []Containers `yaml:"containers,omitempty"` 11 | TerminationGracePeriodSeconds int `yaml:"terminationGracePeriodSeconds,omitempty"` 12 | } 13 | -------------------------------------------------------------------------------- /test/node/express_mongodb/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_mongodb/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - mongodb 19 | -------------------------------------------------------------------------------- /test/node/express_mysql_pg/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_mysql_pg/src/ 5 | command: npm start 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mysql 10 | - mysql:mysql.cloud66.local 11 | - postgresql 12 | - postgresql:postgresql.cloud66.local 13 | environment: 14 | - PORT=3000 15 | mysql: 16 | image: mysql 17 | postgresql: 18 | image: postgres 19 | -------------------------------------------------------------------------------- /packs/ruby/webservers/unicorn.go: -------------------------------------------------------------------------------- 1 | package webservers 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Unicorn struct { 6 | packs.WebServerBase 7 | } 8 | 9 | func (u *Unicorn) Names() []string { 10 | return []string{"unicorn"} 11 | } 12 | 13 | func (u *Unicorn) Port(command *string) string { 14 | return u.WebServerBase.Port(u, command) 15 | } 16 | 17 | func (u *Unicorn) DefaultPort() string { 18 | return "8080" 19 | } 20 | -------------------------------------------------------------------------------- /test/node/Dockerfile.base: -------------------------------------------------------------------------------- 1 | 2 | FROM node:latest 3 | 4 | ENV APP_HOME /app 5 | RUN mkdir -pv $APP_HOME 6 | WORKDIR $APP_HOME 7 | 8 | ADD . $APP_HOME 9 | 10 | ENV NODE_ENV production 11 | ENV NPM_CONFIG_LOGLEVEL warn 12 | 13 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 14 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 15 | # RUN npm config set strict-ssl false 16 | # RUN npm config set registry $CUSTOM_REGISTRY 17 | 18 | RUN npm install 19 | -------------------------------------------------------------------------------- /test/node/express_bare_mongo/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_bare_mongo/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - mongodb 19 | -------------------------------------------------------------------------------- /test/node/express_bare_mysql/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_bare_mysql/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - mysql 19 | -------------------------------------------------------------------------------- /transform/transformer-interface.go: -------------------------------------------------------------------------------- 1 | package transform 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/definitions/docker-compose" 5 | "github.com/cloud66-oss/starter/definitions/kubernetes" 6 | "github.com/cloud66-oss/starter/definitions/service-yml" 7 | ) 8 | 9 | type Transformer interface { 10 | ToServiceYml() service_yml.ServiceYml 11 | ToDockerCompose() docker_compose.DockerCompose 12 | ToKubernetes() kubernetes.Kubernetes 13 | } 14 | -------------------------------------------------------------------------------- /packs/python/webservers/gunicorn.go: -------------------------------------------------------------------------------- 1 | package webservers 2 | 3 | import "github.com/cloud66-oss/starter/packs" 4 | 5 | type Gunicorn struct { 6 | packs.WebServerBase 7 | } 8 | 9 | func (g *Gunicorn) Names() []string { 10 | return []string{"gunicorn"} 11 | } 12 | 13 | func (g *Gunicorn) Port(command *string) string { 14 | return g.WebServerBase.Port(g, command) 15 | } 16 | 17 | func (g *Gunicorn) DefaultPort() string { 18 | return "8000" 19 | } 20 | -------------------------------------------------------------------------------- /test/node/express_pg_procfile/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: _env:WEB 9 | build_root: test/node/express_pg_procfile/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - postgresql 19 | -------------------------------------------------------------------------------- /test/node/express_mysql_pg/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_mysql_pg/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - mysql 19 | - postgresql 20 | -------------------------------------------------------------------------------- /Dockerfile.crosscompile: -------------------------------------------------------------------------------- 1 | #use the golang base image 2 | FROM golang:1.12 3 | MAINTAINER Cloud 66 4 | 5 | #get all the go crosscompile stuff 6 | RUN go get github.com/mitchellh/gox 7 | 8 | #copy the source files 9 | RUN mkdir -p /usr/local/go/src/github.com/cloud66-oss/starter 10 | ADD . /usr/local/go/src/github.com/cloud66-oss/starter 11 | 12 | #switch to our app directory 13 | WORKDIR /usr/local/go/src/github.com/cloud66-oss/starter 14 | 15 | RUN ./compile.sh 16 | -------------------------------------------------------------------------------- /bundle/templates/template.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Template struct { 4 | Version string `json:"version"` 5 | Public bool `json:"public"` 6 | Name string `json:"name"` 7 | Icon string `json:"icon"` 8 | LongName string `json:"long_name"` 9 | Description string `json:"description"` 10 | Templates *Templates `json:"templates"` 11 | } -------------------------------------------------------------------------------- /test/node/express_mongodb_redis/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: npm start 9 | build_root: test/node/express_mongodb_redis/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | databases: 18 | - mongodb 19 | - redis 20 | -------------------------------------------------------------------------------- /test/ruby/sinatra_mongo/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/ruby/23080/src/ 5 | command: bundle exec rackup -E _env:RACK_ENV 6 | ports: 7 | - "9292:9292" 8 | links: 9 | - redis 10 | - redis:redis.cloud66.local 11 | - mongo 12 | - mongo:mongodb.cloud66.local 13 | environment: 14 | - RAILS_ENV=production 15 | - RACK_ENV=production 16 | redis: 17 | image: redis 18 | mongo: 19 | image: mongo 20 | -------------------------------------------------------------------------------- /bundle/templates/workflow.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Workflow struct { 4 | Name string `json:"name"` 5 | Filename string `json:"filename"` 6 | Description string `json:"description"` 7 | Tags []string `json:"tags"` 8 | Dependencies []string `json:"dependencies"` 9 | } 10 | 11 | func (v Workflow) GetName() string { 12 | return v.Name 13 | } 14 | 15 | func (v Workflow) GetDependencies() []string { 16 | return v.Dependencies 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | compiled 10 | artifacts 11 | 12 | # Architecture specific extensions/prefixes 13 | *.[568vq] 14 | [568vq].out 15 | 16 | *.cgo1.go 17 | *.cgo2.c 18 | _cgo_defun.c 19 | _cgo_gotypes.go 20 | _cgo_export.* 21 | .DS_store 22 | 23 | _testmain.go 24 | 25 | *.exe 26 | *.test 27 | *.prof 28 | starter 29 | .vagrant 30 | 31 | .idea 32 | /build 33 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/src/config/database.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | adapter: mysql2 3 | encoding: utf8 4 | pool: 100 5 | timeout: 5000 6 | database: <%= ENV['MYSQL_DATABASE'] %> 7 | username: <%= ENV['MYSQL_USERNAME'] %> 8 | password: <%= ENV['MYSQL_PASSWORD'] %> 9 | 10 | development: 11 | <<: *default 12 | 13 | test: 14 | <<: *default 15 | database: cappexchange_test 16 | 17 | staging: 18 | <<: *default 19 | 20 | production: 21 | <<: *default 22 | -------------------------------------------------------------------------------- /test/node/express_bare/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_mongodb/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_mysql_pg/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_procfile/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/ruby/sinatra_mongo/src/Gemfile: -------------------------------------------------------------------------------- 1 | source "http://rubygems.org/" 2 | 3 | gem 'rake' 4 | 5 | gem 'hiredis' 6 | gem 'redis', :require => ["redis", "redis/connection/hiredis"] 7 | 8 | gem 'json' 9 | 10 | gem 'mongoid' 11 | 12 | gem 'sidekiq' 13 | gem 'sidekiq-status' 14 | 15 | gem 'newrelic_rpm' 16 | 17 | gem 'dotenv' 18 | 19 | gem 'sinatra' 20 | gem 'sinatra-contrib', require: false 21 | 22 | gem 'vine' 23 | 24 | gem 'bugsnag' 25 | 26 | gem 'aws-sdk', '~> 2' 27 | 28 | gem 'httparty' 29 | -------------------------------------------------------------------------------- /test/node/express_bare_mongo/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_bare_mysql/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_mongodb_redis/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_pg_procfile/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /test/node/express_mongodb_procfile/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | 3 | FROM node:4.6 4 | 5 | ENV APP_HOME /app 6 | RUN mkdir -pv $APP_HOME 7 | WORKDIR $APP_HOME 8 | 9 | ADD . $APP_HOME 10 | 11 | ENV NODE_ENV production 12 | ENV NPM_CONFIG_LOGLEVEL warn 13 | 14 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 15 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 16 | # RUN npm config set strict-ssl false 17 | # RUN npm config set registry $CUSTOM_REGISTRY 18 | 19 | RUN npm install 20 | -------------------------------------------------------------------------------- /bundle/templates/policy.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Policy struct { 4 | Name string `json:"name"` 5 | Filename string `json:"filename"` 6 | Dependencies []string `json:"dependencies"` 7 | MinUsage int `json:"min_usage"` 8 | MaxUsage int `json:"max_usage"` 9 | Tags []string `json:"tags"` 10 | } 11 | 12 | func (v Policy) GetName() string { 13 | return v.Name 14 | } 15 | 16 | func (v Policy) GetDependencies() []string { 17 | return v.Dependencies 18 | } 19 | -------------------------------------------------------------------------------- /test/node/express_bare_mysql/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example_nodejs", 3 | "version": "1.0.0", 4 | "description": "test", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "express": "^4.13.4", 13 | "mysql": "^2.10.2" 14 | }, 15 | "repository": { 16 | "type": "git", 17 | "url": "git://github.com/username/repository.git" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /bundle/templates/filter.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Filter struct { 4 | Name string `json:"name"` 5 | Description string `json:"description"` 6 | Filename string `json:"filename"` 7 | Tags []string `json:"tags"` 8 | MinUsage int `json:"min_usage"` 9 | Dependencies []string `json:"dependencies"` 10 | } 11 | 12 | func (v Filter) GetName() string { 13 | return v.Name 14 | } 15 | 16 | func (v Filter) GetDependencies() []string { 17 | return v.Dependencies 18 | } 19 | -------------------------------------------------------------------------------- /test/ruby/sinatra_mongo/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: bundle exec rackup -E _env:RACK_ENV 9 | build_root: test/ruby/23080/src/ 10 | ports: 11 | - container: 9292 12 | http: 80 13 | https: 443 14 | env_vars: 15 | RAILS_ENV: production 16 | RACK_ENV: production 17 | 18 | databases: 19 | - redis 20 | - mongodb 21 | -------------------------------------------------------------------------------- /test/node/express_bare_mongo/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-api", 3 | "main": "server.js", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/scotch-io/node-token-authentication" 7 | }, 8 | "scripts": { 9 | "start": "node server.js" 10 | }, 11 | "author": "Chris Sevilleja ", 12 | "license": "MIT", 13 | "dependencies": { 14 | "express": "~4.0.0", 15 | "morgan": "~1.0.0", 16 | "mongoose": "~5.7.7", 17 | "body-parser": "~1.0.1" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packs/analysis-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | type AnalysisBase struct { 6 | PackName string 7 | LanguageVersion string 8 | GitURL string 9 | GitBranch string 10 | Framework string 11 | FrameworkVersion string 12 | SupportedLanguageVersions []string 13 | Messages common.Lister 14 | Databases []string 15 | ListOfStartCommands []string 16 | } 17 | -------------------------------------------------------------------------------- /test/node/express_rethinkdb/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | deploy_command: NODE_ENV=production webpack 9 | command: NODE_ENV=production node server.babel.js 10 | build_root: test/node/express_rethinkdb/src/ 11 | ports: 12 | - container: 3000 13 | http: 80 14 | https: 443 15 | 16 | rethinkdb: 17 | image: rethinkdb 18 | ports: ["28015","29015"] -------------------------------------------------------------------------------- /packs/node/detector.go: -------------------------------------------------------------------------------- 1 | package node 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Detector struct { 11 | packs.PackElement 12 | } 13 | 14 | func (d *Detector) Detect(rootDir string) bool { 15 | if common.FileExists(filepath.Join(rootDir, "Gemfile")) || common.FileExists(filepath.Join(rootDir, "config", "database.yml")) { 16 | return false 17 | } 18 | return common.FileExists(filepath.Join(rootDir, "package.json")) 19 | } 20 | -------------------------------------------------------------------------------- /bundle/templates/transformation.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Transformation struct { 4 | Name string `json:"name"` 5 | Filename string `json:"filename"` 6 | Dependencies []string `json:"dependencies"` 7 | MinUsage int `json:"min_usage"` 8 | MaxUsage int `json:"max_usage"` 9 | Tags []string `json:"tags"` 10 | } 11 | 12 | func (v Transformation) GetName() string { 13 | return v.Name 14 | } 15 | 16 | func (v Transformation) GetDependencies() []string { 17 | return v.Dependencies 18 | } 19 | -------------------------------------------------------------------------------- /definitions/docker-compose/deploy.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Deploy struct { 4 | Replicas int `yaml:"replicas,omitempty"` 5 | UpdateConfig UpdateConfig `yaml:"update_config,omitempty"` 6 | RestartPolicy RestartPolicy `yaml:"restart_policy,omitempty"` 7 | Mode string `yaml:"mode,omitempty"` 8 | Placement Placement `yaml:"placement,omitempty"` 9 | Resources Resources `yaml:"resources,omitempty"` 10 | Labels map[string]string `yaml:"labels,omitempty"` 11 | } 12 | -------------------------------------------------------------------------------- /common/lister.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type Lister struct { 8 | Items []string 9 | } 10 | 11 | func NewLister(seed ...string) *Lister { 12 | l := &Lister{} 13 | l.Items = seed 14 | 15 | return l 16 | } 17 | 18 | func (l *Lister) ToList(sep string) string { 19 | return strings.Join(l.Items, sep) 20 | } 21 | 22 | func (l *Lister) Add(items ...string) { 23 | for _, item := range items { 24 | l.Items = append(l.Items, item) 25 | } 26 | } 27 | 28 | func (l *Lister) Contains(item string) bool { 29 | return ContainsString(l.Items, item) 30 | } 31 | -------------------------------------------------------------------------------- /definitions/service-yml/port.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | type Ports []Port 4 | 5 | type Port struct { 6 | Container int `yaml:"container,omitempty"` 7 | Http int `yaml:"http,omitempty"` 8 | Https int `yaml:"https,omitempty"` 9 | Tcp int `yaml:"tcp,omitempty"` 10 | Udp int `yaml:"udp,omitempty"` 11 | } 12 | 13 | type tempPort struct { 14 | Container string `yaml:"container,omitempty"` 15 | Http string `yaml:"http,omitempty"` 16 | Https string `yaml:"https,omitempty"` 17 | Tcp string `yaml:"tcp,omitempty"` 18 | Udp string `yaml:"udp,omitempty"` 19 | } 20 | -------------------------------------------------------------------------------- /test/node/express_mongodb_procfile/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | web: 4 | build: test/node/express_mongodb_procfile/src/ 5 | command: node lib/index.js 6 | ports: 7 | - "3000:3000" 8 | links: 9 | - mongodb 10 | - mongodb:mongodb.cloud66.local 11 | environment: 12 | - PORT=3000 13 | background: 14 | build: test/node/express_mongodb_procfile/src/ 15 | command: node lib/background.js 16 | ports: 17 | - "3001:3001" 18 | links: 19 | - mongodb 20 | - mongodb:mongodb.cloud66.local 21 | environment: 22 | - PORT=3001 23 | mongodb: 24 | image: mongo 25 | -------------------------------------------------------------------------------- /packs/pack-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | const ( 6 | btrSuffix = "generic" 7 | genericStencilTemplatePath = "https://raw.githubusercontent.com/cloud66/stencils/{{.branch}}/" 8 | genericGithubURL = "https://github.com/cloud66/stencils.git" 9 | ) 10 | 11 | type PackBase struct { 12 | Messages *common.Lister 13 | } 14 | 15 | func GenericBundleSuffix() string { 16 | return btrSuffix 17 | } 18 | 19 | func GenericTemplateRepository() string { 20 | return genericStencilTemplatePath 21 | } 22 | 23 | func GithubURL() string { 24 | return genericGithubURL 25 | } 26 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/api/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | custom_web: 6 | git_url: fake.git 7 | git_branch: master 8 | command: bundle exec rails s -p 3000 -E _env:RAILS_ENV -D 9 | build_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:schema:load" 10 | deploy_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:migrate" 11 | build_root: . 12 | ports: 13 | - container: 3000 14 | http: 80 15 | https: 443 16 | env_vars: 17 | RAILS_ENV: production 18 | RACK_ENV: production 19 | 20 | databases: 21 | - mysql 22 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: bundle exec unicorn -v 9 | build_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:schema:load" 10 | deploy_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:migrate" 11 | build_root: test/ruby/rails_unicorn_mysql/src/ 12 | ports: 13 | - container: 8080 14 | http: 80 15 | https: 443 16 | env_vars: 17 | RAILS_ENV: production 18 | RACK_ENV: production 19 | 20 | databases: 21 | - mysql 22 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | custom_web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: bundle exec rails s -p 3000 -E _env:RAILS_ENV -D 9 | build_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:schema:load" 10 | deploy_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:migrate" 11 | build_root: test/ruby/rails_mysql/src/ 12 | ports: 13 | - container: 3000 14 | http: 80 15 | https: 443 16 | env_vars: 17 | RAILS_ENV: production 18 | RACK_ENV: production 19 | 20 | databases: 21 | - mysql 22 | -------------------------------------------------------------------------------- /transform/kubes-transformer.go: -------------------------------------------------------------------------------- 1 | package transform 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/definitions/docker-compose" 5 | "github.com/cloud66-oss/starter/definitions/kubernetes" 6 | "github.com/cloud66-oss/starter/definitions/service-yml" 7 | ) 8 | 9 | type KubesTransformer struct { 10 | Base kubernetes.Kubernetes 11 | } 12 | 13 | func (k *KubesTransformer) ToKubernetes() kubernetes.Kubernetes { 14 | return k.Base 15 | } 16 | 17 | func (k *KubesTransformer) ToServiceYml() service_yml.ServiceYml { 18 | return service_yml.ServiceYml{} 19 | } 20 | 21 | func (k *KubesTransformer) ToDockerCompose() docker_compose.DockerCompose { 22 | return docker_compose.DockerCompose{} 23 | } 24 | -------------------------------------------------------------------------------- /packs/service-yml-to-kubes/analyzer.go: -------------------------------------------------------------------------------- 1 | package service_yml_to_kubes 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/packs" 5 | "path/filepath" 6 | ) 7 | 8 | type Analyzer struct { 9 | packs.AnalyzerBase 10 | ServiceYml string 11 | } 12 | 13 | func (a *Analyzer) Analyze() (*Analysis, error) { 14 | a.ServiceYml = filepath.Join(a.RootDir, "service.yml") 15 | gitURL, gitBranch, _, err := a.ProjectMetadata() 16 | if err != nil { 17 | return nil, err 18 | } 19 | analysis := &Analysis{ 20 | AnalysisBase: packs.AnalysisBase{ 21 | PackName: a.GetPack().Name(), 22 | GitBranch: gitBranch, 23 | GitURL: gitURL, 24 | Messages: a.Messages}, 25 | } 26 | return analysis, nil 27 | } 28 | -------------------------------------------------------------------------------- /bundle/templates/helm-release.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type HelmRelease struct { 4 | Name string `json:"name"` 5 | Description string `json:"description"` 6 | Tags []string `json:"tags"` 7 | ChartRepositoryUrl string `json:"chart_repository_url"` 8 | ChartName string `json:"chart_name"` 9 | ChartVersion string `json:"chart_version"` 10 | Dependencies []string `json:"dependencies"` 11 | Modifiers []*Modifier `json:"modifiers"` 12 | } 13 | 14 | func (v HelmRelease) GetName() string { 15 | return v.Name 16 | } 17 | 18 | func (v HelmRelease) GetDependencies() []string { 19 | return v.Dependencies 20 | } 21 | -------------------------------------------------------------------------------- /packs/web-server-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import "github.com/cloud66-oss/starter/common" 4 | 5 | type WebServerBase struct { 6 | } 7 | 8 | func (b *WebServerBase) Port(w WebServer, command *string) string { 9 | withoutPortEnvVar := w.RemovePortIfEnvVar(*command) 10 | *command = withoutPortEnvVar 11 | hasFound, port := w.ParsePort(*command) 12 | if hasFound { 13 | return port 14 | } else { 15 | return w.DefaultPort() 16 | } 17 | } 18 | 19 | func (w *WebServerBase) ParsePort(command string) (hasFound bool, port string) { 20 | return common.ParsePort(command) 21 | } 22 | 23 | func (w *WebServerBase) RemovePortIfEnvVar(command string) string { 24 | return common.RemovePortIfEnvVar(command) 25 | } 26 | -------------------------------------------------------------------------------- /definitions/kubernetes/containers.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | type Containers struct { 4 | Name string `yaml:"name,omitempty"` 5 | Command []string `yaml:"command,omitempty"` 6 | Image string `yaml:"image,omitempty"` 7 | Resources Resources `yaml:"resources,omitempty"` 8 | WorkingDir string `yaml:"workingDir,omitempty"` 9 | SecurityContext SecurityContext `yaml:"securityContext,omitempty"` 10 | VolumeMounts []VolumeMounts `yaml:"volumeMounts,omitempty"` 11 | Env []EnvVar `yaml:"env,omitempty"` 12 | Ports []Port `yaml:"ports,omitempty"` 13 | Lifecycle Lifecycle `yaml:"lifecycle,omitempty"` 14 | } 15 | -------------------------------------------------------------------------------- /definitions/docker-compose/build.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Build struct { 4 | Context string `yaml:"context,omitempty"` 5 | Dockerfile string `yaml:"dockerfile,omitempty"` 6 | Args map[string]string `yaml:"args,omitempty"` 7 | CacheFrom []string `yaml:"cache_from,omitempty"` 8 | Labels []string `yaml:"labels,omitempty"` 9 | } 10 | 11 | type BuildAux struct { 12 | Context string `yaml:"context,omitempty"` 13 | Dockerfile string `yaml:"dockerfile,omitempty"` 14 | Args map[string]string `yaml:"args,omitempty"` 15 | CacheFrom []string `yaml:"cache_from,omitempty"` 16 | Labels []string `yaml:"labels,omitempty"` 17 | } 18 | -------------------------------------------------------------------------------- /test/node/express_mongodb_procfile/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: node lib/index.js 9 | build_root: test/node/express_mongodb_procfile/src/ 10 | ports: 11 | - container: 3000 12 | http: 80 13 | https: 443 14 | env_vars: 15 | PORT: 3000 16 | 17 | background: 18 | git_url: git@github.com:cloud66/starter.git 19 | git_branch: master 20 | command: node lib/background.js 21 | build_root: test/node/express_mongodb_procfile/src/ 22 | ports: 23 | - container: 3001 24 | env_vars: 25 | PORT: 3001 26 | 27 | databases: 28 | - mongodb 29 | -------------------------------------------------------------------------------- /templates/docker-compose.yml.template: -------------------------------------------------------------------------------- 1 | --- 2 | {{range .Services}} 3 | {{.Name}}: 4 | build: {{.BuildRoot}} 5 | command: {{.Command}} 6 | {{if .Ports}} 7 | ports: 8 | {{range .Ports}} 9 | {{if eq .Container "80"}} 10 | - "3000:{{.Container}}" 11 | {{else}} 12 | - "{{.Container}}:{{.Container}}" 13 | {{end}} 14 | {{end}} 15 | {{end}} 16 | {{if .Databases}} 17 | links: 18 | {{range .Databases}} 19 | - {{.Name}} 20 | - {{.Name}}:{{.Name}}.cloud66.local 21 | {{end}} 22 | {{end}} 23 | {{if .EnvVars}} 24 | environment:{{range .EnvVars}} 25 | - {{.Key}}={{.Value}} 26 | {{end}}{{end}} 27 | {{end}} 28 | 29 | {{if .Dbs}} 30 | {{range .Dbs}} 31 | {{.Name}}: 32 | image: {{.DockerImage}} 33 | {{end}} 34 | {{end}} -------------------------------------------------------------------------------- /test/service_yml/service_to_kubes_1/src/service.yml: -------------------------------------------------------------------------------- 1 | # Generated with <3 by Cloud66 2 | 3 | services: 4 | cakephp: 5 | volumes: 6 | - /.:/var/www/html/ 7 | - _env(WIERD_ENV_VAR):/somewhere 8 | - /somewhere:other-place:ro 9 | env_vars: 10 | MYSQL_PASSWORD: root 11 | ports: 12 | - container: 3000 13 | - container: 80 14 | http: 8000 15 | - container: 3000 16 | http: 330 17 | - container: 443 18 | http: 8443 19 | git_url: http://github.com/saada/docker-compose-php-mysql.git 20 | git_branch: master 21 | dockerfile_path: Dockerfile 22 | requires: 23 | - mysql 24 | mysql: 25 | image: mysql:5.6 26 | volumes: 27 | - /mysql-data:/var/lib/mysql 28 | env_vars: 29 | ENV: some value 30 | -------------------------------------------------------------------------------- /packs/docker-compose-yaml-writer-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | 7 | "github.com/cloud66-oss/starter/common" 8 | ) 9 | 10 | type DockerComposeYAMLWriterBase struct { 11 | PackElement 12 | TemplateWriterBase 13 | } 14 | 15 | func (w *DockerComposeYAMLWriterBase) Write(context interface{}) error { 16 | templateName := fmt.Sprintf("%s.docker-compose.yml.template", w.GetPack().Name()) 17 | if !common.FileExists(filepath.Join(w.TemplateDir, templateName)) { 18 | templateName = "docker-compose.yml.template" // fall back on generic template 19 | } 20 | err := w.WriteTemplate(templateName, "docker-compose.yml", context) 21 | if err != nil { 22 | return err 23 | } 24 | 25 | return w.removeBlankLines("docker-compose.yml") 26 | } 27 | -------------------------------------------------------------------------------- /packs/compose-to-service-yml/analyzer.go: -------------------------------------------------------------------------------- 1 | package compose_to_service_yml 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/packs" 5 | "path/filepath" 6 | ) 7 | 8 | type Analyzer struct { 9 | packs.AnalyzerBase 10 | DockerCompose string 11 | } 12 | 13 | func (a *Analyzer) Analyze() (*Analysis, error) { 14 | a.DockerCompose = filepath.Join(a.RootDir, "docker-compose.yml") 15 | gitURL, gitBranch, _, err := a.ProjectMetadata() 16 | if err != nil { 17 | return nil, err 18 | } 19 | 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | analysis := &Analysis{ 25 | AnalysisBase: packs.AnalysisBase{ 26 | PackName: a.GetPack().Name(), 27 | GitBranch: gitBranch, 28 | GitURL: gitURL, 29 | Messages: a.Messages}, 30 | } 31 | return analysis, nil 32 | } 33 | -------------------------------------------------------------------------------- /bundle/templates/stencil.go: -------------------------------------------------------------------------------- 1 | package templates 2 | 3 | type Stencil struct { 4 | Name string `json:"name"` 5 | FilenamePattern string `json:"filename_pattern"` 6 | Filename string `json:"filename"` 7 | Description string `json:"description"` 8 | Contextemplates string `json:"context_type"` 9 | Tags []string `json:"tags"` 10 | PreferredSequence int `json:"preferred_sequence"` 11 | Suggested bool `json:"suggested"` 12 | MinUsage int `json:"min_usage"` 13 | MaxUsage int `json:"max_usage"` 14 | Dependencies []string `json:"dependencies"` 15 | } 16 | 17 | func (v Stencil) GetName() string { 18 | return v.Name 19 | } 20 | 21 | func (v Stencil) GetDependencies() []string { 22 | return v.Dependencies 23 | } 24 | -------------------------------------------------------------------------------- /bundle/bundles/bundle.go: -------------------------------------------------------------------------------- 1 | package bundles 2 | 3 | type Bundle struct { 4 | Version string `json:"version"` 5 | Metadata *Metadata `json:"metadata"` 6 | UID string `json:"uid"` 7 | Name string `json:"name"` 8 | BaseTemplates []*BaseTemplate `json:"base_templates"` 9 | Policies []*Policy `json:"policies"` 10 | Transformations []*Transformation `json:"transformations"` 11 | Workflows []*Workflow `json:"workflows"` 12 | HelmReleases []*HelmRelease `json:"helm_releases"` 13 | Filters []*Filter `json:"filters"` 14 | Tags []string `json:"tags"` 15 | Configurations []string `json:"configuration"` 16 | ConfigStore []string `json:"configstore"` 17 | } 18 | -------------------------------------------------------------------------------- /utils/update.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/khash/updater" 8 | ) 9 | 10 | func UpdateExec(channel string) { 11 | update(false, channel) 12 | 13 | fmt.Println("Updated") 14 | } 15 | 16 | func update(silent bool, channel string) { 17 | fmt.Println("Inside the update method with channel : ", channel) 18 | worker, err := updater.NewUpdater(Version, &updater.Options{ 19 | RemoteURL: "https://s3.amazonaws.com/downloads.cloud66.com/starter/", 20 | Channel: Channel, 21 | Silent: silent, 22 | }) 23 | if err != nil { 24 | if !silent { 25 | fmt.Println(err) 26 | os.Exit(1) 27 | } 28 | 29 | os.Exit(0) 30 | } 31 | 32 | err = worker.Run(channel != Channel) 33 | if err != nil { 34 | if !silent { 35 | fmt.Println(err) 36 | os.Exit(1) 37 | } 38 | 39 | os.Exit(0) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | #use the golang base image 2 | FROM golang:1.13 3 | #copy the source files 4 | RUN mkdir -p /go/src/github.com/cloud66-oss/starter 5 | #switch to our app directory 6 | WORKDIR /go/src/github.com/cloud66-oss/starter 7 | # add the app code 8 | ADD . /go/src/github.com/cloud66-oss/starter 9 | # run build commands 10 | RUN bash -c "env GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -a -installsuffix cgo -o compiled/starter ." 11 | #--------- 12 | # use the alpine base image 13 | FROM alpine:latest 14 | RUN apk --update upgrade && apk --no-cache add curl ca-certificates && rm -rf /var/cache/apk/* 15 | RUN mkdir -p /app 16 | # copy the binary 17 | COPY --from=0 /go/src/github.com/cloud66-oss/starter/compiled/starter /app 18 | COPY ./templates /app/templates 19 | # start command 20 | WORKDIR /app 21 | CMD /app/starter -daemon -templates templates -registry true 22 | -------------------------------------------------------------------------------- /config.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" 6 | ) 7 | 8 | // Config holds configuration for Starter 9 | type Config struct { 10 | APIURL string 11 | template_path string 12 | use_registry bool 13 | } 14 | 15 | // ReadFromFile reads config from a file 16 | func ReadFromFile(configFile string) (*Config, error) { 17 | var config *Config 18 | data, err := ioutil.ReadFile(configFile) 19 | if err != nil { 20 | return nil, err 21 | } 22 | 23 | if err := json.Unmarshal(data, &config); err != nil { 24 | return nil, err 25 | } 26 | 27 | config.SetDefaults() 28 | 29 | return config, nil 30 | } 31 | 32 | // SetDefaults sets default values for unset config items 33 | func (c *Config) SetDefaults() error { 34 | if c.APIURL == "" { 35 | c.APIURL = "0.0.0.0:9090" 36 | } 37 | c.use_registry = false 38 | return nil 39 | } 40 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | custom_web: 4 | build: test/ruby/rails_jobs_unicorn_redis_postgresql/src/ 5 | command: bundle exec unicorn_rails -c config/unicorn.rb -E _env:RAILS_ENV _env:DAEMONIZE 6 | ports: 7 | - "8080:8080" 8 | links: 9 | - postgresql 10 | - postgresql:postgresql.cloud66.local 11 | - redis 12 | - redis:redis.cloud66.local 13 | environment: 14 | - RAILS_ENV=production 15 | - RACK_ENV=production 16 | worker: 17 | build: test/ruby/rails_jobs_unicorn_redis_postgresql/src/ 18 | command: bundle exec sidekiq 19 | links: 20 | - postgresql 21 | - postgresql:postgresql.cloud66.local 22 | - redis 23 | - redis:redis.cloud66.local 24 | environment: 25 | - RAILS_ENV=production 26 | - RACK_ENV=production 27 | postgresql: 28 | image: postgresql 29 | redis: 30 | image: redis 31 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/expected/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | worker: 4 | build: test/ruby/15333/src/ 5 | command: bundle exec rake jobs:work 6 | links: 7 | - mysql 8 | - mysql:mysql.cloud66.local 9 | - postgresql 10 | - postgresql:postgresql.cloud66.local 11 | - redis 12 | - redis:redis.cloud66.local 13 | environment: 14 | - RAILS_ENV=production 15 | - RACK_ENV=production 16 | web: 17 | build: test/ruby/15333/src/ 18 | command: bundle exec rails server -e _env:RAILS_ENV 19 | ports: 20 | - "3000:3000" 21 | links: 22 | - mysql 23 | - mysql:mysql.cloud66.local 24 | - postgresql 25 | - postgresql:postgresql.cloud66.local 26 | - redis 27 | - redis:redis.cloud66.local 28 | environment: 29 | - RAILS_ENV=production 30 | - RACK_ENV=production 31 | mysql: 32 | image: mysql 33 | postgresql: 34 | image: postgresql 35 | redis: 36 | image: redis 37 | -------------------------------------------------------------------------------- /templates/ruby.dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM ruby:{{.Version}} 2 | 3 | RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 4 | RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list 5 | RUN apt-get update -qq && apt-get install -y build-essential nodejs yarn {{.Packages.ToList " "}} 6 | 7 | ENV APP_HOME /app 8 | RUN mkdir $APP_HOME 9 | WORKDIR $APP_HOME 10 | 11 | # This installs bundler 2x. Change if you need any of the older versions 12 | RUN gem install bundler:2.1.2 13 | ADD Gemfile* $APP_HOME/ 14 | # This is a bundler 2 format. For bundler 1, you can add --without development test to the bundle install line 15 | RUN bundle config set without 'development test' 16 | RUN bundle install 17 | 18 | ADD . $APP_HOME 19 | # if you're not using webpack, you can comment out the following line 20 | RUN yarn install --check-files 21 | RUN SECRET_KEY_BASE=$SECRET_KEY_BASE RAILS_ENV=production bundle exec rake assets:precompile 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/cloud66-oss/starter 2 | 3 | go 1.15 4 | 5 | require ( 6 | github.com/ant0ine/go-json-rest v3.3.2+incompatible 7 | github.com/blang/semver v3.5.1+incompatible 8 | github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054 // indirect 9 | github.com/cloud66-oss/cloud66 v0.0.0-20200826132808-49389c091094 10 | github.com/getsentry/raven-go v0.2.0 11 | github.com/hashicorp/go-version v1.2.1 12 | github.com/heroku/docker-registry-client v0.0.0-20190909225348-afc9e1acc3d5 13 | github.com/khash/updater v0.0.0-20200903131458-458863e5af61 14 | github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d 15 | github.com/mitchellh/go-homedir v1.1.0 16 | github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e // indirect 17 | github.com/onsi/ginkgo v1.14.2 18 | github.com/onsi/gomega v1.10.3 19 | github.com/satori/go.uuid v1.2.0 20 | github.com/sethvargo/go-password v0.2.0 21 | gopkg.in/resty.v1 v1.12.0 22 | gopkg.in/yaml.v2 v2.4.0 23 | ) 24 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | worker: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: bundle exec rake jobs:work 9 | build_root: test/ruby/15333/src/ 10 | env_vars: 11 | RAILS_ENV: production 12 | RACK_ENV: production 13 | 14 | web: 15 | git_url: git@github.com:cloud66/starter.git 16 | git_branch: master 17 | command: bundle exec rails server -e _env:RAILS_ENV 18 | build_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:schema:load" 19 | deploy_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:migrate" 20 | build_root: test/ruby/15333/src/ 21 | ports: 22 | - container: 3000 23 | http: 80 24 | https: 443 25 | env_vars: 26 | RAILS_ENV: production 27 | RACK_ENV: production 28 | 29 | databases: 30 | - mysql 31 | - postgresql 32 | - redis 33 | -------------------------------------------------------------------------------- /templates/service.yml.template: -------------------------------------------------------------------------------- 1 | --- 2 | services: 3 | {{range .Services}} 4 | ##NEWLINE## 5 | {{.Name}}: 6 | git_url: {{.GitRepo}} 7 | git_branch: {{.GitBranch}} 8 | command: {{.Command}} 9 | {{if .BuildCommand}}build_command: {{.BuildCommand}}{{end}} 10 | {{if .DeployCommand}}deploy_command: {{.DeployCommand}}{{end}} 11 | build_root: {{.BuildRoot}} 12 | 13 | {{if .Ports}}ports:{{range .Ports}} 14 | - {{if .Container}}container: {{.Container}}{{end}} 15 | {{if .HTTP}}http: {{.HTTP}}{{end}} 16 | {{if .HTTPS}}https: {{.HTTPS}}{{end}} 17 | {{if .TCP}}tcp: {{.TCP}}{{end}} 18 | {{if .UDP}}udp: {{.UDP}}{{end}} 19 | {{end}}{{end}} 20 | 21 | {{if .Tags}}tags: {{ range $_, $value := .Tags}} 22 | - {{$value}} 23 | {{end}}{{end}} 24 | 25 | {{if .EnvVars}}env_vars:{{range .EnvVars}} 26 | {{.Key}}: {{.Value}} 27 | {{end}}{{end}} 28 | {{end}} 29 | 30 | {{if .Dbs}} 31 | ##NEWLINE## 32 | databases:{{range .Dbs}} 33 | - {{.Name}} 34 | {{end}}{{end}} 35 | -------------------------------------------------------------------------------- /packs/pack-interface.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | type Pack interface { 4 | Name() string 5 | LanguageVersion() string 6 | Framework() string 7 | FrameworkVersion() string 8 | FilesToBeAnalysed() []string 9 | Detector() Detector 10 | Analyze(rootDir string, environment string, shouldNotPrompt bool, git_repo string, git_branch string) error 11 | WriteDockerfile(templateDir string, outputDir string, shouldNotPrompt bool) error 12 | WriteServiceYAML(templateDir string, outputDir string, shouldNotPrompt bool) error 13 | WriteDockerComposeYAML(templateDir string, outputDir string, shouldNotPrompt bool) error 14 | WriteKubesConfig(outputDir string, shouldNotPrompt bool) error 15 | GetMessages() []string 16 | GetDatabases() []string 17 | GetStartCommands() []string 18 | GetSupportedLanguageVersions() []string 19 | SetSupportedLanguageVersions(versions []string) 20 | CreateSkycapFiles(outputDir string, templateDir string, branch string) error 21 | StencilRepositoryPath() string 22 | PackGithubUrl() string 23 | FrameworkTag() string 24 | LanguageTag() string 25 | } 26 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | --- 3 | services: 4 | 5 | custom_web: 6 | git_url: git@github.com:cloud66/starter.git 7 | git_branch: master 8 | command: bundle exec unicorn_rails -c config/unicorn.rb -E _env:RAILS_ENV _env:DAEMONIZE 9 | build_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:schema:load" 10 | deploy_command: /bin/sh -c "RAILS_ENV=_env:RAILS_ENV bundle exec rake db:migrate" 11 | build_root: test/ruby/rails_jobs_unicorn_redis_postgresql/src/ 12 | ports: 13 | - container: 8080 14 | http: 80 15 | https: 443 16 | env_vars: 17 | RAILS_ENV: production 18 | RACK_ENV: production 19 | 20 | worker: 21 | git_url: git@github.com:cloud66/starter.git 22 | git_branch: master 23 | command: bundle exec sidekiq 24 | build_root: test/ruby/rails_jobs_unicorn_redis_postgresql/src/ 25 | env_vars: 26 | RAILS_ENV: production 27 | RACK_ENV: production 28 | 29 | databases: 30 | - postgresql 31 | - redis 32 | -------------------------------------------------------------------------------- /templates/templates.json: -------------------------------------------------------------------------------- 1 | { 2 | "version" : "1.0.3", 3 | "dockerfiles" : [ 4 | { "name": "node.dockerfile.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/node.dockerfile.template"}, 5 | { "name": "python.dockerfile.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/python.dockerfile.template"}, 6 | { "name": "ruby.dockerfile.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/ruby.dockerfile.template"}, 7 | { "name": "php.dockerfile.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/php.dockerfile.template"} 8 | ], 9 | "service-ymls" : [ 10 | { "name": "service.yml.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/service.yml.template"} 11 | ], 12 | "docker-compose-ymls" : [ 13 | { "name": "docker-compose.yml.template", "url" : "https://raw.githubusercontent.com/cloud66/starter/{{.branch}}/templates/docker-compose.yml.template"} 14 | ] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /starter_suite_test.go: -------------------------------------------------------------------------------- 1 | package main_test 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | . "github.com/onsi/ginkgo" 6 | . "github.com/onsi/gomega" 7 | "os/exec" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | var binPath string = "./starter" 13 | 14 | func TestStarter(t *testing.T) { 15 | RegisterFailHandler(Fail) 16 | RunSpecs(t, "Starter Suite") 17 | } 18 | 19 | var _ = BeforeSuite(func() { 20 | current_date := time.Now().Format("2006-01-02") 21 | 22 | err := exec.Command("go", "build", "-ldflags", "-X \"main.VERSION=test\" -X \"main.BUILDDATE="+current_date+"\"").Run() 23 | Expect(err).NotTo(HaveOccurred()) 24 | Expect(common.FileExists(binPath)).To(BeTrue()) 25 | 26 | err = exec.Command(binPath, "-daemon", "-templates", "templates").Start() 27 | 28 | // daemon takes time to start up - works fine without waiting in a Docker container, but codeship needs some time to start it 29 | time.Sleep(5 * time.Second) 30 | 31 | Expect(err).NotTo(HaveOccurred()) 32 | }) 33 | 34 | var _ = AfterSuite(func() { 35 | err := exec.Command("rm", binPath).Run() 36 | Expect(err).NotTo(HaveOccurred()) 37 | }) 38 | -------------------------------------------------------------------------------- /definitions/service-yml/service-yml-base.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | 8 | "gopkg.in/yaml.v2" 9 | ) 10 | 11 | type ServiceYml struct { 12 | Services map[string]Service `yaml:"services,omitempty"` 13 | Databases []string `yaml:"databases,omitempty"` 14 | } 15 | 16 | func (s *ServiceYml) UnmarshalFromFile(path string) error { 17 | var err error 18 | _, err = os.Stat(path) 19 | CheckError(err) 20 | 21 | yamlFile, err := ioutil.ReadFile(path) 22 | 23 | serviceYml := ServiceYml{ 24 | Services: map[string]Service{}, 25 | Databases: make([]string, 1), 26 | } 27 | 28 | if err := yaml.Unmarshal([]byte(yamlFile), &serviceYml); err != nil { 29 | fmt.Println(err.Error()) 30 | } 31 | s.Services = serviceYml.Services 32 | s.Databases = serviceYml.Databases 33 | 34 | return nil 35 | } 36 | 37 | func (s ServiceYml) MarshalToFile(path string) error { 38 | file, err := yaml.Marshal(s) 39 | 40 | file = []byte("# Generated with <3 by Cloud66\n\n" + string(file)) 41 | 42 | err = ioutil.WriteFile(path, file, 0644) 43 | CheckError(err) 44 | 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /common/utils-php.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | // "fmt" 5 | "encoding/json" 6 | "io/ioutil" 7 | //"strings" 8 | "regexp" 9 | ) 10 | 11 | // Looks for node version in the package.json. If found returns true, version if not false, "" 12 | func GetPHPVersion(composerJSONfile string) (bool, string) { 13 | buf, err := ioutil.ReadFile(composerJSONfile) 14 | if err != nil { 15 | return false, err.Error() 16 | } 17 | 18 | var data map[string](interface{}) 19 | err = json.Unmarshal(buf, &data) 20 | 21 | if err != nil { 22 | return false, err.Error() 23 | } 24 | 25 | if data["require"] == nil { 26 | return false, "" 27 | } 28 | 29 | if phpVersion, ok := data["require"].(map[string]interface{})["php"].(string); ok { 30 | re := regexp.MustCompile("[0-9][.][0-9]") 31 | return true, re.FindString(phpVersion) 32 | } else { 33 | return false, "" 34 | } 35 | 36 | } 37 | 38 | func GetFramework(composerJSONfile string, framework string) (bool, string) { 39 | return true, framework 40 | } 41 | 42 | func GetPHPDatabase(composerJSONfile string, databaseName string) (bool, string) { 43 | return true, databaseName 44 | } 45 | -------------------------------------------------------------------------------- /definitions/kubernetes/kubernetes-base.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | 8 | "gopkg.in/yaml.v2" 9 | 10 | docker_compose "github.com/cloud66-oss/starter/definitions/docker-compose" 11 | ) 12 | 13 | type Kubernetes struct { 14 | Services []KubesService 15 | Deployments []KubesDeployment 16 | } 17 | 18 | func (k Kubernetes) UnmarshalFromFile(path string) error { 19 | //needs changes if used 20 | var err error 21 | _, err = os.Stat(path) 22 | docker_compose.CheckError(err) 23 | 24 | yamlFile, err := ioutil.ReadFile(path) 25 | 26 | kubernetes := Kubernetes{ 27 | Services: []KubesService{}, 28 | Deployments: []KubesDeployment{}, 29 | } 30 | 31 | if err := yaml.Unmarshal([]byte(yamlFile), &kubernetes); err != nil { 32 | fmt.Println(err.Error()) 33 | } 34 | return nil 35 | } 36 | 37 | func (k Kubernetes) MarshalToFile(path string) error { 38 | 39 | file := []byte("# Generated with <3 by Cloud66\n\n") 40 | file = composeWriter(file, k.Deployments, k.Services) 41 | 42 | err := ioutil.WriteFile(path, file, 0644) 43 | docker_compose.CheckError(err) 44 | 45 | return nil 46 | } 47 | -------------------------------------------------------------------------------- /definitions/docker-compose/docker-compose-base.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | import ( 4 | "fmt" 5 | "gopkg.in/yaml.v2" 6 | "io/ioutil" 7 | "os" 8 | ) 9 | 10 | type DockerCompose struct { 11 | Services map[string]Service 12 | Version string 13 | } 14 | 15 | func (d *DockerCompose) UnmarshalFromFile(path string) error { 16 | var err error 17 | _, err = os.Stat(path) 18 | CheckError(err) 19 | 20 | yamlFile, err := ioutil.ReadFile(path) 21 | 22 | dockerCompose := DockerCompose{ 23 | Services: make(map[string]Service), 24 | Version: "", 25 | } 26 | 27 | if err := yaml.Unmarshal([]byte(yamlFile), &dockerCompose); err != nil { 28 | fmt.Println(err.Error()) 29 | } 30 | 31 | if len(dockerCompose.Services) == 0 { 32 | err = yaml.Unmarshal([]byte(yamlFile), &dockerCompose.Services) 33 | CheckError(err) 34 | } 35 | 36 | d.Services = dockerCompose.Services 37 | d.Version = dockerCompose.Version 38 | 39 | return nil 40 | } 41 | 42 | func (d DockerCompose) MarshalToFile(path string) error { 43 | file, err := yaml.Marshal(d) 44 | file = []byte("# Generated with <3 by Cloud66\n\n" + string(file)) 45 | 46 | err = ioutil.WriteFile(path, file, 0644) 47 | if err != nil { 48 | return err 49 | } 50 | 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /test/php/Dockerfile.base: -------------------------------------------------------------------------------- 1 | FROM php:latest-apache 2 | #install all the dependencies 3 | RUN apt-get update && apt-get install -y \ 4 | libicu-dev \ 5 | libpq-dev \ 6 | libmcrypt-dev \ 7 | git \ 8 | zip \ 9 | unzip \ 10 | && rm -r /var/lib/apt/lists/* \ 11 | && docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \ 12 | && docker-php-ext-install \ 13 | intl \ 14 | mbstring \ 15 | mcrypt \ 16 | pcntl \ 17 | pdo_mysql \ 18 | pdo_pgsql \ 19 | pgsql \ 20 | zip \ 21 | opcache 22 | 23 | #install composer 24 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer 25 | 26 | #create project folder 27 | ENV APP_HOME /app 28 | RUN mkdir $APP_HOME 29 | WORKDIR $APP_HOME 30 | 31 | #change uid and gid of apache to docker user uid/gid 32 | RUN usermod -u 1000 www-data && groupmod -g 1000 www-data 33 | 34 | #change apache setting 35 | RUN sed -i -e "s/var\/www/app/g" /etc/apache2/apache2.conf && sed -i -e "s/html/public/g" /etc/apache2/apache2.conf 36 | RUN a2enmod rewrite 37 | 38 | #copy source files and run composer 39 | COPY . $APP_HOME 40 | RUN composer install --no-interaction 41 | 42 | #change ownership 43 | RUN chown -R www-data:www-data $APP_HOME 44 | 45 | -------------------------------------------------------------------------------- /templates/php.dockerfile.template: -------------------------------------------------------------------------------- 1 | FROM php:{{.Version}}-apache 2 | #install all the dependencies 3 | RUN apt-get update && apt-get install -y \ 4 | libicu-dev \ 5 | libpq-dev \ 6 | libmcrypt-dev \ 7 | git \ 8 | zip \ 9 | unzip \ 10 | && rm -r /var/lib/apt/lists/* \ 11 | && docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \ 12 | && docker-php-ext-install \ 13 | intl \ 14 | mbstring \ 15 | mcrypt \ 16 | pcntl \ 17 | pdo_mysql \ 18 | pdo_pgsql \ 19 | pgsql \ 20 | zip \ 21 | opcache 22 | 23 | #install composer 24 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer 25 | 26 | #create project folder 27 | ENV APP_HOME /app 28 | RUN mkdir $APP_HOME 29 | WORKDIR $APP_HOME 30 | 31 | #change uid and gid of apache to docker user uid/gid 32 | RUN usermod -u 1000 www-data && groupmod -g 1000 www-data 33 | 34 | #change apache setting 35 | RUN sed -i -e "s/var\/www/app/g" /etc/apache2/apache2.conf && sed -i -e "s/html/public/g" /etc/apache2/apache2.conf 36 | RUN a2enmod rewrite 37 | 38 | #copy source files and run composer 39 | COPY . $APP_HOME 40 | RUN composer install --no-interaction 41 | 42 | #change ownership 43 | RUN chown -R www-data:www-data $APP_HOME 44 | 45 | -------------------------------------------------------------------------------- /test/php/laravel_bare_mysql/expected/Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by Cloud66 Starter 2 | FROM php:5.5-apache 3 | #install all the dependencies 4 | RUN apt-get update && apt-get install -y \ 5 | libicu-dev \ 6 | libpq-dev \ 7 | libmcrypt-dev \ 8 | git \ 9 | zip \ 10 | unzip \ 11 | && rm -r /var/lib/apt/lists/* \ 12 | && docker-php-ext-configure pdo_mysql --with-pdo-mysql=mysqlnd \ 13 | && docker-php-ext-install \ 14 | intl \ 15 | mbstring \ 16 | mcrypt \ 17 | pcntl \ 18 | pdo_mysql \ 19 | pdo_pgsql \ 20 | pgsql \ 21 | zip \ 22 | opcache 23 | 24 | #install composer 25 | RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer 26 | 27 | #create project folder 28 | ENV APP_HOME /app 29 | RUN mkdir $APP_HOME 30 | WORKDIR $APP_HOME 31 | 32 | #change uid and gid of apache to docker user uid/gid 33 | RUN usermod -u 1000 www-data && groupmod -g 1000 www-data 34 | 35 | #change apache setting 36 | RUN sed -i -e "s/var\/www/app/g" /etc/apache2/apache2.conf && sed -i -e "s/html/public/g" /etc/apache2/apache2.conf 37 | RUN a2enmod rewrite 38 | 39 | #copy source files and run composer 40 | COPY . $APP_HOME 41 | RUN composer install --no-interaction 42 | 43 | #change ownership 44 | RUN chown -R www-data:www-data $APP_HOME 45 | 46 | -------------------------------------------------------------------------------- /common/utils-python.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "io/ioutil" 5 | "os/exec" 6 | "path/filepath" 7 | "regexp" 8 | "strings" 9 | ) 10 | 11 | func GetPythonVersion() (hasFound bool, version string) { 12 | cmd := exec.Command("python", "--version") 13 | b, err := cmd.CombinedOutput() // NOTE: cmd.Output() would not work here because the Python version is written on stderr 14 | if err != nil { 15 | return false, "" 16 | } 17 | return true, strings.TrimSpace(strings.Split(string(b), " ")[1]) 18 | } 19 | 20 | func IsDjangoProject(rootDir string) bool { 21 | return FileExists(filepath.Join(rootDir, "manage.py")) 22 | } 23 | 24 | func PythonPackages(requirementsTxt string) ([]string, error) { 25 | packageRegexp := regexp.MustCompile(`(?m)^(\w+)`) 26 | includeRegexp := regexp.MustCompile(`(?m)^-r[[:blank:]]+(.*)[[:blank:]]*$`) 27 | 28 | content, err := ioutil.ReadFile(requirementsTxt) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | var packages []string 34 | for _, match := range packageRegexp.FindAllStringSubmatch(string(content), -1) { 35 | packages = append(packages, match[1]) 36 | } 37 | 38 | for _, match := range includeRegexp.FindAllStringSubmatch(string(content), -1) { 39 | otherPackages, err := PythonPackages(match[1]) 40 | if err != nil { 41 | return nil, err 42 | } 43 | packages = append(packages, otherPackages...) 44 | } 45 | 46 | return packages, nil 47 | } 48 | -------------------------------------------------------------------------------- /test/node/express_mongodb_procfile/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LiveChan", 3 | "version": "0.0.1", 4 | "description": "A live multimedia sharing chatroom.", 5 | "main": "web.js", 6 | "_comment_1": "we should probably change the main script, it shouldn't start a server, says http://package.json.nodejitsu.com/ (hover over the main part on there)", 7 | "scripts": { 8 | "start": "node lib/index.js", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/emgram769/live4chan.git" 14 | }, 15 | "keywords": [ 16 | "live", 17 | "ajax", 18 | "imageboard", 19 | "chat" 20 | ], 21 | "author": "emgram769", 22 | "license": "AGPL-3.0", 23 | "dependencies": { 24 | "bcrypt": "0.8.7", 25 | "captcha": "0.0.4", 26 | "canvas": "1.2.11", 27 | "express": "3.4.8", 28 | "logfmt": "0.18.1", 29 | "socket.io": "0.9.16", 30 | "tripcode": "1.2.0", 31 | "mongoose": "5.7.7", 32 | "async": "0.2.10", 33 | "socket.io-stream": "0.5.2", 34 | "read": "1.0.5", 35 | "geoip": "*" 36 | }, 37 | "devDependencies": { 38 | "bower": "1.2.8", 39 | "uglify-js": "2.4.12" 40 | }, 41 | "engine": "node >= 0.10.0", 42 | "bugs": { 43 | "url": "https://github.com/emgram769/live4chan/issues" 44 | }, 45 | "homepage": "https://github.com/emgram769/live4chan" 46 | } 47 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # CHANGELOG 2 | 3 | ## V1.3.1 4 | 5 | Disable docker-compose and kubernetes packs for API mode. 6 | 7 | ## V1.3.0 8 | 9 | This release will support the direct convertion from a `service.yml` to the `kubernetes.yml` format. This give you the option to run a Cloud 66 service definition on your local Kubernetes cluster (for example minikube). The `kubernetes` pack will be available to be used both through the API and the CLI tool. 10 | 11 | ## V1.2.0 12 | 13 | This release will support the direct convertion from a `docker-compose.yml` to the `service.yml` format. The `docker-compose` pack will be available to be used both through the API and the CLI tool. 14 | 15 | ## V1.1.0 16 | 17 | This release will support API mode. You can use Starter as a microservice to analyse codebases on demand. Also, this version will use Docker Registry to check if a specific version public version exists. We add Meteor support to the Node buildpack. The binaries are compiled using Go 1.7 (compatible with macOS Sierra) 18 | 19 | ## V1.0.3 20 | 21 | Support for nodejs and PHP 22 | 23 | ## V1.0.2 24 | 25 | Includes support for compose.yml generation 26 | 27 | ## V1.0.1 28 | 29 | Bump up version 30 | 31 | ## V1.0.0 - Initial Alpha 32 | 33 | This is the first release of Cloud 66 Starter. This is an alpha release, however running it does no harm as it only writes a Dockerfile and service.yml in the project directory. You can manually modify the files and commit them into your repository once you're happy with them. 34 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/src/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby "2.1.2" 3 | 4 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 5 | gem 'rails', '4.1.4' 6 | # Use mysql as the database for Active Record 7 | gem 'mysql2' 8 | # Use SCSS for stylesheets 9 | gem 'sass-rails', '~> 4.0.3' 10 | # Use Uglifier as compressor for JavaScript assets 11 | gem 'uglifier', '>= 1.3.0' 12 | # Use CoffeeScript for .js.coffee assets and views 13 | gem 'coffee-rails', '~> 4.0.0' 14 | # See https://github.com/sstephenson/execjs#readme for more supported runtimes 15 | # gem 'therubyracer', platforms: :ruby 16 | 17 | # Use jquery as the JavaScript library 18 | gem 'jquery-rails' 19 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 20 | gem 'turbolinks' 21 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 22 | gem 'jbuilder', '~> 2.0' 23 | # bundle exec rake doc:rails generates the API under doc/api. 24 | gem 'sdoc', '~> 0.4.0', group: :doc 25 | 26 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 27 | gem 'spring', group: :development 28 | 29 | # Use ActiveModel has_secure_password 30 | # gem 'bcrypt', '~> 3.1.7' 31 | 32 | # Use unicorn as the app server 33 | # gem 'unicorn' 34 | 35 | # Use Capistrano for deployment 36 | # gem 'capistrano-rails', group: :development 37 | 38 | # Use debugger 39 | # gem 'debugger', group: [:development, :test] 40 | 41 | -------------------------------------------------------------------------------- /cli_test.go: -------------------------------------------------------------------------------- 1 | package main_test 2 | 3 | import ( 4 | "fmt" 5 | . "github.com/onsi/ginkgo" 6 | . "github.com/onsi/gomega" 7 | "os/exec" 8 | "time" 9 | ) 10 | 11 | var helpText string 12 | var versionText string 13 | 14 | var _ = Describe("Running Starter", func() { 15 | 16 | BeforeEach(func() { 17 | version := "test" 18 | current_date := time.Now().Format("2006-01-02") 19 | 20 | helpText = fmt.Sprintf("Starter (%s) Help\n", version) 21 | versionText = fmt.Sprintf("Starter version: %s (%s)\n", version, current_date) 22 | 23 | }) 24 | 25 | Context("using the help flag", func() { 26 | It("should show the help", func() { 27 | command := exec.Command(binPath, "help") 28 | command_out, err := command.Output() 29 | output_string := string(command_out) 30 | Expect(string(output_string)).To(Equal(helpText)) 31 | Expect(err).NotTo(HaveOccurred()) 32 | }) 33 | }) 34 | Context("using the version flag", func() { 35 | It("should show the version", func() { 36 | command := exec.Command(binPath, "version") 37 | command_out, err := command.Output() 38 | output_string := string(command_out) 39 | Expect(string(output_string)).To(Equal(versionText)) 40 | Expect(err).NotTo(HaveOccurred()) 41 | }) 42 | }) 43 | Context("using the -v flag", func() { 44 | It("should show the version", func() { 45 | command := exec.Command(binPath, "-v") 46 | command_out, err := command.Output() 47 | output_string := string(command_out) 48 | Expect(string(output_string)).To(Equal(versionText)) 49 | Expect(err).NotTo(HaveOccurred()) 50 | }) 51 | }) 52 | }) 53 | -------------------------------------------------------------------------------- /definitions/service-yml/custom-yaml-unmarsahler.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | import ( 4 | "log" 5 | "strconv" 6 | 7 | "gopkg.in/yaml.v2" 8 | ) 9 | 10 | func (t *TrafficMatches) UnmarshalYAML(unmarshal func(interface{}) error) error { 11 | var multi *TrafficMatches 12 | err := unmarshal(multi) 13 | if err != nil { 14 | var single string 15 | err := unmarshal(&single) 16 | if err != nil { 17 | return err 18 | } 19 | t = &TrafficMatches{single} 20 | } else { 21 | t = multi 22 | } 23 | return nil 24 | } 25 | 26 | func (p *Ports) UnmarshalYAML(unmarshal func(interface{}) error) error { 27 | 28 | var ports interface{} 29 | 30 | err := unmarshal(&ports) 31 | if err != nil { 32 | log.Fatalf("yaml.Unmarshal: %v", err) 33 | } 34 | switch ports := ports.(type) { 35 | case string: 36 | *p = append(*p, shortPortToLong(ports)) 37 | case []interface{}: 38 | for _, vv := range ports { 39 | switch vv := vv.(type) { 40 | case string: 41 | *p = append(*p, shortPortToLong(vv)) 42 | case int: 43 | vvi := strconv.Itoa(vv) 44 | *p = append(*p, shortPortToLong(vvi)) 45 | case map[interface{}]interface{}: 46 | var longSyntaxStringPort tempPort 47 | var longSyntaxPort Port 48 | temp, er := yaml.Marshal(vv) 49 | CheckError(er) 50 | er = yaml.Unmarshal(temp, &longSyntaxStringPort) 51 | longSyntaxPort = stringToInt(longSyntaxStringPort) 52 | CheckError(er) 53 | *p = append(*p, longSyntaxPort) 54 | default: 55 | log.Fatal("Failed to unmarshal ") 56 | } 57 | } 58 | default: 59 | log.Fatal("Failed to unmarshal") 60 | 61 | } 62 | 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /test/node/express_pg_procfile/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name" : "leslie-eric.us", 3 | "description": "The open source website for Leslie Verploegen's and Eric Ferraiuolo's wedding.", 4 | "homepage" : "http://leslie-eric.us/", 5 | "version" : "1.8.0", 6 | "private" : true, 7 | 8 | "author": "Eric Ferraiuolo (http://ericf.me/)", 9 | 10 | "license": "MIT", 11 | 12 | "directories": { 13 | "lib" : "./lib", 14 | "middleware": "./middleware", 15 | "public" : "./public", 16 | "routes" : "./routes", 17 | "scripts" : "./scripts", 18 | "views" : "./views" 19 | }, 20 | 21 | "main": "server", 22 | 23 | "engines": { 24 | "node": ">=0.8.x", 25 | "npm" : ">=1.1.2" 26 | }, 27 | 28 | "dependencies": { 29 | "async" : "0.2.x", 30 | "bower" : "1.2.x", 31 | "combohandler" : "0.2.x", 32 | "csv" : "0.3.x", 33 | "db-migrate" : "0.4.x", 34 | "deep-freeze" : "latest", 35 | "express" : "3.2.x", 36 | "express-slash" : "latest", 37 | "express-state" : "latest", 38 | "express3-handlebars": "latest", 39 | "handlebars" : "1.0.x", 40 | "pg" : "1.1.x", 41 | "request" : "2.25.0" 42 | }, 43 | 44 | "scripts": { 45 | "install": "./node_modules/bower/bin/bower install", 46 | "migrate-up": "./node_modules/db-migrate/bin/db-migrate up -e default --config config/migrations.json" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated with <3 by Cloud66 2 | 3 | services: 4 | client: 5 | git_url: git@github.com:cloud66/starter.git 6 | git_branch: master 7 | build_root: client 8 | requires: 9 | - haproxy 10 | tags: 11 | this_is_a_label: first 12 | env_vars: 13 | FOREMAN_URL: http://haproxy 14 | db: 15 | image: postgres:9.5 16 | env_vars: 17 | PGDATA: /var/lib/postgresql/data/pgdata 18 | volumes: 19 | - /./pgdata:/var/lib/postgresql/data/pgdata 20 | foreman: 21 | git_url: git@github.com:cloud66/starter.git 22 | git_branch: master 23 | dockerfile_path: ./here 24 | ports: 25 | - http: 80 26 | volumes: 27 | - /./assets:/usr/src/app/public/assets 28 | - /mydata1:/data1 29 | - /mydata3:/data3 30 | - /./webpack:/usr/src/app/public/webpack 31 | foreman-init: 32 | git_url: git@github.com:cloud66/starter.git 33 | git_branch: master 34 | build_root: foreman 35 | requires: 36 | - db 37 | volumes: 38 | - /./assets:/usr/src/app/public/assets 39 | - /./webpack:/usr/src/app/public/webpack 40 | haproxy: 41 | image: dockercloud/haproxy 42 | ports: 43 | - container: 8443 44 | - container: 8000 45 | http: 8000 46 | - container: 80 47 | http: 80 48 | - container: 80 49 | http: 8080 50 | volumes: 51 | - /var/run/docker.sock:/var/run/docker.sock 52 | memcache: 53 | image: memcached 54 | proxy: 55 | git_url: git@github.com:cloud66/starter.git 56 | git_branch: master 57 | build_root: proxy 58 | ports: 59 | - container: 8000 60 | http: 8000 61 | -------------------------------------------------------------------------------- /test/php/laravel_bare_mysql/src/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "laravel/laravel", 3 | "description": "The Laravel Framework.", 4 | "keywords": ["framework", "laravel"], 5 | "license": "MIT", 6 | "type": "project", 7 | "require": { 8 | "php": ">=5.5.9", 9 | "laravel/framework": "5.2.*", 10 | "laravelcollective/html": "5.2.*", 11 | "bestmomo/filemanager": "1.1.*" 12 | }, 13 | "require-dev": { 14 | "fzaninotto/faker": "~1.4", 15 | "mockery/mockery": "0.9.*", 16 | "phpunit/phpunit": "~4.0", 17 | "symfony/css-selector": "2.8.*|3.0.*", 18 | "symfony/dom-crawler": "2.8.*|3.0.*" 19 | }, 20 | "autoload": { 21 | "classmap": [ 22 | "database" 23 | ], 24 | "files": [ 25 | "app/helpers.php" 26 | ], 27 | "psr-4": { 28 | "App\\": "app/" 29 | } 30 | }, 31 | "autoload-dev": { 32 | "classmap": [ 33 | "tests/TestCase.php" 34 | ] 35 | }, 36 | "scripts": { 37 | "post-root-package-install": [ 38 | "php -r \"copy('.env.example', '.env');\"" 39 | ], 40 | "post-create-project-cmd": [ 41 | "php artisan key:generate" 42 | ], 43 | "post-install-cmd": [ 44 | "Illuminate\\Foundation\\ComposerScripts::postInstall", 45 | "php artisan optimize" 46 | ], 47 | "post-update-cmd": [ 48 | "Illuminate\\Foundation\\ComposerScripts::postUpdate", 49 | "php artisan optimize" 50 | ] 51 | }, 52 | "config": { 53 | "preferred-install": "dist" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose_2/expected/service.yml: -------------------------------------------------------------------------------- 1 | # Generated with <3 by Cloud66 2 | 3 | services: 4 | db: 5 | image: mariadb 6 | env_vars: 7 | MYSQL_ALLOW_EMPTY_PASSWORD: "yes" 8 | MYSQL_USER: root 9 | NODE_ENV: _env(NODE_ENV) 10 | PORT: _env(PORT) 11 | RACK_ENV: Env_var_from_file 12 | RACK2: a second env var from file 13 | VIRTUAL_HOST: _env(VIRTUAL_HOST) 14 | VIRTUAL_PORT: _env(PORT) 15 | volumes: 16 | - _env(LOG_ROOT):/var/log 17 | - /data_mariadb-vol:/var/lib/mysql 18 | es24: 19 | image: sergeyzskw/elasticsearch:2.4-magento-smile 20 | requires: 21 | - db 22 | volumes: 23 | - /es24-vol:/usr/share/elasticsearch/data 24 | http: 25 | image: sergeyzskw/apache2 26 | requires: 27 | - php70 28 | volumes: 29 | - _env(LOG_ROOT):/var/log 30 | - /http_a2-vol:/etc/apache2 31 | - _env(HTTPD_DOCUMENT_ROOT):/var/www 32 | php55: 33 | image: sergeyzskw/php:5.5-fpm 34 | requires: 35 | - es24 36 | volumes: 37 | - _env(LOG_ROOT):/var/log 38 | - /php_55-vol:/etc/php5 39 | - /composer_55-vol:/home/composer/.composer 40 | - /~/.ssh/_env(SSH_KEY):/home/composer/.ssh/id_rsa 41 | - /~/.ssh/known_hosts:/home/composer/.ssh/known_hosts 42 | - _env(HTTPD_DOCUMENT_ROOT):/var/www 43 | php70: 44 | image: sergeyzskw/php:7.0-fpm 45 | requires: 46 | - php55 47 | volumes: 48 | - _env(LOG_ROOT):/var/log 49 | - /php_70-vol:/etc/php 50 | - /composer_70-vol:/home/composer/.composer 51 | - /~/.ssh/_env(SSH_KEY):/home/composer/.ssh/id_rsa 52 | - /~/.ssh/known_hosts:/home/composer/.ssh/known_hosts 53 | - _env(HTTPD_DOCUMENT_ROOT):/var/www 54 | -------------------------------------------------------------------------------- /test/ruby/rails_mysql/src/config/database.yml: -------------------------------------------------------------------------------- 1 | # MySQL. Versions 5.0+ are recommended. 2 | # 3 | # Install the MYSQL driver 4 | # gem install mysql2 5 | # 6 | # Ensure the MySQL gem is defined in your Gemfile 7 | # gem 'mysql2' 8 | # 9 | # And be sure to use new-style password hashing: 10 | # http://dev.mysql.com/doc/refman/5.0/en/old-client.html 11 | # 12 | default: &default 13 | adapter: mysql2 14 | encoding: utf8 15 | pool: 5 16 | username: root 17 | host: <%= ENV['MYSQL_DATABASE_HOST'] %> 18 | 19 | development: 20 | <<: *default 21 | database: rails-mysql-app_development 22 | 23 | # Warning: The database defined as "test" will be erased and 24 | # re-generated from your development database when you run "rake". 25 | # Do not set this db to the same as development or production. 26 | test: 27 | <<: *default 28 | database: rails-mysql-app_test 29 | 30 | # As with config/secrets.yml, you never want to store sensitive information, 31 | # like your database password, in your source code. If your source code is 32 | # ever seen by anyone, they now have access to your database. 33 | # 34 | # Instead, provide the password as a unix environment variable when you boot 35 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 36 | # for a full rundown on how to provide these environment variables in a 37 | # production deployment. 38 | # 39 | # On Heroku and other platform providers, you may have a full connection URL 40 | # available as an environment variable. For example: 41 | # 42 | # DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase" 43 | # 44 | # You can use this database configuration with: 45 | # 46 | # production: 47 | # url: <%= ENV['DATABASE_URL'] %> 48 | # 49 | production: 50 | <<: *default 51 | database: rails-mysql-app_production 52 | username: rails-mysql-app 53 | password: <%= ENV['RAILS-MYSQL-APP_DATABASE_PASSWORD'] %> 54 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose/src/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | memcache: 4 | image: memcached 5 | db: 6 | image: postgres:9.5 7 | environment: 8 | - PGDATA=/var/lib/postgresql/data/pgdata 9 | volumes: 10 | - ./pgdata:/var/lib/postgresql/data/pgdata:z 11 | foreman: 12 | build: 13 | context: ./somewhere 14 | dockerfile: ./here 15 | command: rails server -p 80 -b 0.0.0.0 16 | ports: 17 | - 80 18 | volumes: 19 | - ./assets:/usr/src/app/public/assets:z 20 | - type: volume 21 | source: mydata1 22 | target: /data1 23 | - type: bind 24 | source: mydata2 25 | target: /data2 26 | - type: volume 27 | source: mydata3 28 | target: /data3 29 | - ./webpack:/usr/src/app/public/webpack:z 30 | links: 31 | - db 32 | - memcache 33 | - proxy 34 | haproxy: 35 | image: dockercloud/haproxy 36 | expose: 37 | - 8443 38 | volumes: 39 | - /var/run/docker.sock:/var/run/docker.sock 40 | links: 41 | - foreman 42 | ports: 43 | - 8000:8000 44 | - 80:80 45 | - target: 80 46 | published: 8080 47 | protocol: tcp 48 | mode: host 49 | proxy: 50 | build: proxy 51 | command: /usr/src/app/bin/smart-proxy 52 | ports: 53 | - 8000:8000 54 | client: 55 | deploy: 56 | resources: 57 | limits: 58 | cpus: "2131" 59 | memory: '321' 60 | labels: 61 | this_is_a_label: first 62 | build: client 63 | environment: 64 | - FOREMAN_URL=http://haproxy 65 | depends_on: 66 | - haproxy 67 | foreman-init: 68 | build: foreman 69 | command: bundle exec rake db:migrate db:seed assets:clean assets:precompile webpack:compile apipie:cache:index 70 | volumes: 71 | - ./assets:/usr/src/app/public/assets 72 | - ./webpack:/usr/src/app/public/webpack 73 | depends_on: 74 | - db 75 | -------------------------------------------------------------------------------- /test/service_yml/service_to_kubes_2/src/service.yml: -------------------------------------------------------------------------------- 1 | # Generated with <3 by Cloud66 2 | 3 | services: 4 | client: 5 | git_url: http://github.com/saada/docker-compose-php-mysql.git 6 | git_branch: master 7 | build_root: client 8 | requires: 9 | - haproxy 10 | ports: 11 | - 9000:9000 12 | tags: 13 | this_is_a_label: first 14 | env_vars: 15 | FOREMAN_URL: http://haproxy 16 | db: 17 | image: postgres:9.5 18 | volumes: 19 | - /pgdata:/var/lib/postgresql/data/pgdata:z 20 | env_vars: 21 | PGDATA: /var/lib/postgresql/data/pgdata 22 | foreman: 23 | git_url: http://github.com/saada/docker-compose-php-mysql.git 24 | git_branch: master 25 | build_root: ./somewhere 26 | volumes: 27 | - /assets:/usr/src/app/public/assets:z 28 | - /webpack:/usr/src/app/public/webpack:z 29 | - /mydata1:/data1 30 | - /mydata3:/data3 31 | dockerfile_path: ./here 32 | command: rails server -p 80 -b 0.0.0.0 33 | ports: 34 | - "4480" 35 | foreman-init: 36 | git_url: http://github.com/saada/docker-compose-php-mysql.git 37 | git_branch: master 38 | build_root: foreman 39 | requires: 40 | - db 41 | ports: 42 | - 123:345:567 43 | volumes: 44 | - /assets:/usr/src/app/public/assets 45 | - /webpack:/usr/src/app/public/webpack 46 | command: bundle exec rake db:migrate db:seed assets:clean assets:precompile webpack:compile 47 | apipie:cache:index 48 | haproxy: 49 | image: dockercloud/haproxy 50 | volumes: 51 | - /var/run/docker.sock:/var/run/docker.sock 52 | ports: 53 | - "8443" 54 | - 90:8000 55 | - 80:80 56 | - container: "3080" 57 | http: "8080" 58 | memcache: 59 | image: memcached 60 | ports: 61 | - 23 62 | proxy: 63 | git_url: http://github.com/saada/docker-compose-php-mysql.git 64 | git_branch: master 65 | build_root: proxy 66 | command: /usr/src/app/bin/smart-proxy 67 | ports: 68 | - 9000:9000 69 | 70 | -------------------------------------------------------------------------------- /packs/service-yaml-context-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | service_yml "github.com/cloud66-oss/starter/definitions/service-yml" 6 | "strconv" 7 | ) 8 | 9 | type ServiceYAMLContextBase struct { 10 | Services []*common.Service 11 | Dbs []common.Database 12 | } 13 | 14 | func (s *ServiceYAMLContextBase) GenerateFromServiceYml(serviceYml service_yml.ServiceYml) error { 15 | s.Services = make([]*common.Service, 0) 16 | s.Dbs = make([]common.Database, 0) 17 | 18 | for name, service := range serviceYml.Services { 19 | //migrate from service_yml.Service to common.Service 20 | 21 | ports := make([]*common.PortMapping, 0) 22 | // create for to populate ports 23 | 24 | for _, port := range service.Ports { 25 | ports = append(ports, &common.PortMapping{ 26 | Container: strconv.Itoa(port.Container), 27 | HTTP: strconv.Itoa(port.Http), 28 | HTTPS: strconv.Itoa(port.Https), 29 | TCP: strconv.Itoa(port.Tcp), 30 | UDP: strconv.Itoa(port.Udp), 31 | }) 32 | } 33 | 34 | envs := make([]*common.EnvVar, 0) 35 | 36 | for key, value := range service.EnvVars { 37 | envs = append(envs, &common.EnvVar{ 38 | Key: key, 39 | Value: value, 40 | }) 41 | } 42 | 43 | s.Services = append(s.Services, &common.Service{ 44 | Name: name, 45 | GitRepo: service.GitUrl, 46 | GitBranch: service.GitBranch, 47 | Command: service.Command, 48 | BuildCommand: service.BuildCommand, 49 | DeployCommand: service.DeployCommand, 50 | Tags: service.Tags, 51 | Ports: ports, 52 | EnvVars: envs, 53 | BuildRoot: service.BuildRoot, 54 | Databases: make([]common.Database, 0), 55 | }) 56 | } 57 | 58 | for _, database := range serviceYml.Databases { 59 | //migrate from string to common.Database 60 | s.Dbs = append(s.Dbs, common.Database{ 61 | Name: database, 62 | DockerImage: database, 63 | }) 64 | } 65 | 66 | return nil 67 | } 68 | -------------------------------------------------------------------------------- /test/node/express_mongodb/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hackathon-starter", 3 | "version": "4.2.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "https://github.com/sahat/hackathon-starter.git" 7 | }, 8 | "scripts": { 9 | "start": "node app.js", 10 | "test": "mocha --reporter spec --timeout 5000" 11 | }, 12 | "dependencies": { 13 | "async": "^2.0.1", 14 | "bcrypt-nodejs": "^0.0.3", 15 | "body-parser": "^1.15.2", 16 | "cheerio": "^0.22.0", 17 | "clockwork": "^0.1.4", 18 | "compression": "^1.6.2", 19 | "connect-mongo": "^1.3.2", 20 | "dotenv": "^2.0.0", 21 | "errorhandler": "^1.4.3", 22 | "express": "^4.14.0", 23 | "express-flash": "^0.0.2", 24 | "express-session": "^1.14.0", 25 | "express-validator": "^2.20.8", 26 | "fbgraph": "^1.3.0", 27 | "github-api": "^2.3.0", 28 | "instagram-node": "^0.5.8", 29 | "lastfm": "^0.9.2", 30 | "lob": "^3.9.0", 31 | "lodash": "^4.15.0", 32 | "lusca": "^1.4.1", 33 | "mongoose": "^5.7.6", 34 | "morgan": "^1.7.0", 35 | "multer": "^1.2.0", 36 | "node-foursquare": "^0.3.0", 37 | "node-linkedin": "^0.5.4", 38 | "node-sass-middleware": "^0.9.8", 39 | "nodemailer": "^2.5.0", 40 | "passport": "0.3.2", 41 | "passport-facebook": "^2.1.1", 42 | "passport-github": "^1.1.0", 43 | "passport-google-oauth": "^1.0.0", 44 | "passport-instagram": "^1.0.0", 45 | "passport-linkedin-oauth2": "^1.4.1", 46 | "passport-local": "^1.0.0", 47 | "passport-oauth": "^1.0.0", 48 | "passport-openid": "^0.4.0", 49 | "passport-twitter": "^1.0.4", 50 | "paypal-rest-sdk": "^1.6.9", 51 | "pug": "^2.0.0-beta5", 52 | "request": "^2.74.0", 53 | "stripe": "^4.9.1", 54 | "tumblr.js": "^1.1.1", 55 | "twilio": "^3.3.1-edge", 56 | "twit": "^2.2.4", 57 | "validator": "^5.5.0" 58 | }, 59 | "devDependencies": { 60 | "chai": "^3.5.0", 61 | "mocha": "^3.0.2", 62 | "supertest": "^2.0.0" 63 | }, 64 | "engines": { 65 | "node": "6.1.0" 66 | }, 67 | "license": "MIT" 68 | } 69 | -------------------------------------------------------------------------------- /packs/service-yaml-writer-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "regexp" 9 | "strings" 10 | 11 | "github.com/cloud66-oss/starter/common" 12 | ) 13 | 14 | type ServiceYAMLWriterBase struct { 15 | PackElement 16 | TemplateWriterBase 17 | } 18 | 19 | func (w *ServiceYAMLWriterBase) Write(context interface{}) error { 20 | templateName := fmt.Sprintf("%s.service.yml.template", w.GetPack().Name()) 21 | if !common.FileExists(filepath.Join(w.TemplateDir, templateName)) { 22 | templateName = "service.yml.template" // fall back on generic template 23 | } 24 | err := w.WriteTemplate(templateName, "service.yml", context) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | return w.removeBlankLines("service.yml") 30 | } 31 | 32 | // NOTE 33 | // Templates can have a lot of blank lines when some parts of it are evaluated 34 | // empty. There is currently no way to avoid this with Go templates (See 35 | // https://github.com/golang/go/issues/9969 for more information) 36 | // What we do to avoid this is: 37 | // * Removing all blank lines from the evaluated template 38 | // * If a line contains '##NEWLINE##', replace it by a newline 39 | func (w *TemplateWriterBase) removeBlankLines(name string) error { 40 | fullPath := filepath.Join(w.OutputDir, name) 41 | content, err := ioutil.ReadFile(fullPath) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | blankLinePattern := regexp.MustCompile("^[[:blank:]]*$") 47 | newlinePattern := regexp.MustCompile("^##NEWLINE##$") 48 | 49 | lines := strings.Split(string(content), "\n") 50 | var newContent []string 51 | for _, line := range lines { 52 | if !blankLinePattern.MatchString(line) { 53 | if newlinePattern.MatchString(line) { 54 | newContent = append(newContent, "") 55 | } else { 56 | newContent = append(newContent, line) 57 | } 58 | } 59 | } 60 | newContent = append(newContent, "") // final newline 61 | 62 | file, err := os.Create(fullPath) 63 | if err != nil { 64 | return err 65 | } 66 | defer file.Close() 67 | _, err = file.WriteString(strings.Join(newContent, "\n")) 68 | return err 69 | } 70 | -------------------------------------------------------------------------------- /common/utils-ruby.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "regexp" 7 | "strings" 8 | ) 9 | 10 | var ( 11 | rubyVersionRegex = regexp.MustCompile("ruby\\s['\"](.*?)['\"]") 12 | ) 13 | 14 | // Looks for ruby version in the gemfile. If found returns true, version if not false, "" 15 | func GetRubyVersion(gemFile string) (bool, string) { 16 | buf, err := ioutil.ReadFile(gemFile) 17 | if err != nil { 18 | return false, err.Error() 19 | } 20 | 21 | lines := strings.Split(string(buf), "\n") 22 | for _, line := range lines { 23 | if line == "" || strings.HasPrefix(line, "#") { 24 | continue 25 | } 26 | 27 | if rubyVersionRegex.MatchString(line) { 28 | sm := rubyVersionRegex.FindStringSubmatch(line) 29 | return true, sm[1] 30 | } 31 | } 32 | 33 | return false, "" 34 | } 35 | 36 | // returns bool = found any of the gems or not and string = the version of the first found 37 | func GetGemVersion(gemFile string, gemNames ...string) (bool, string) { 38 | buf, err := ioutil.ReadFile(gemFile) 39 | if err != nil { 40 | return false, err.Error() 41 | } 42 | 43 | lines := strings.Split(string(buf), "\n") 44 | for _, line := range lines { 45 | for _, gemName := range gemNames { 46 | found, version := ParseLineForGem(gemName, line) 47 | if found { 48 | return true, version 49 | } 50 | } 51 | } 52 | 53 | return false, "" 54 | 55 | } 56 | 57 | // Checks a line to see if it contains the given gem. returns true, version or false, "" 58 | func ParseLineForGem(gemName string, line string) (bool, string) { 59 | line = strings.TrimSpace(line) 60 | if line == "" || strings.HasPrefix(line, "#") { 61 | // empty or comment 62 | return false, "" 63 | } 64 | 65 | re := regexp.MustCompile(fmt.Sprintf("gem\\s['\"]%s['\"]\\s*,?\\s*(?P['\"].*?['\"])?", gemName)) 66 | if !re.MatchString(line) { 67 | return false, "" 68 | } else { 69 | sm := re.FindStringSubmatch(line) 70 | 71 | if len(sm) > 0 { 72 | 73 | result := strings.Replace(sm[1], "'", "", -1) 74 | result = strings.Replace(result, "\"", "", -1) 75 | 76 | return true, result 77 | } else { 78 | return true, "" 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /test/docker_compose/just_compose_2/src/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | 3 | services: 4 | http: 5 | container_name: dev-a24 6 | image: sergeyzskw/apache2 7 | volumes: 8 | - ${LOG_ROOT}:/var/log 9 | - http_a2-vol:/etc/apache2 10 | - ${HTTPD_DOCUMENT_ROOT}:/var/www 11 | depends_on: 12 | - php70 13 | links: 14 | - php55:php55.${HOST} 15 | - php70:php70.${HOST} 16 | 17 | php55: 18 | container_name: dev-php55 19 | image: sergeyzskw/php:5.5-fpm 20 | volumes: 21 | - ${LOG_ROOT}:/var/log 22 | - php_55-vol:/etc/php5 23 | - composer_55-vol:/home/composer/.composer 24 | - ~/.ssh/${SSH_KEY}:/home/composer/.ssh/id_rsa 25 | - ~/.ssh/known_hosts:/home/composer/.ssh/known_hosts 26 | - ${HTTPD_DOCUMENT_ROOT}:/var/www 27 | depends_on: 28 | - es24 29 | links: 30 | - db:db.${HOST} 31 | - es24:es24.${HOST} 32 | 33 | php70: 34 | container_name: dev-php70 35 | image: sergeyzskw/php:7.0-fpm 36 | volumes: 37 | - ${LOG_ROOT}:/var/log 38 | - php_70-vol:/etc/php 39 | - composer_70-vol:/home/composer/.composer 40 | - ~/.ssh/${SSH_KEY}:/home/composer/.ssh/id_rsa 41 | - ~/.ssh/known_hosts:/home/composer/.ssh/known_hosts 42 | - ${HTTPD_DOCUMENT_ROOT}:/var/www 43 | depends_on: 44 | - php55 45 | links: 46 | - db:db.${HOST} 47 | - es24:es24.${HOST} 48 | 49 | es24: 50 | container_name: dev-es24 51 | image: sergeyzskw/elasticsearch:2.4-magento-smile 52 | volumes: 53 | - es24-vol:/usr/share/elasticsearch/data 54 | depends_on: 55 | - db 56 | 57 | db: 58 | container_name: dev-db 59 | image: mariadb 60 | environment: 61 | MYSQL_USER: root 62 | MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' 63 | env_file: 64 | - env.env 65 | - settings.env 66 | volumes: 67 | - ${LOG_ROOT}:/var/log 68 | - data_mariadb-vol:/var/lib/mysql 69 | 70 | volumes: 71 | data_mariadb-vol: 72 | http_a2-vol: 73 | php_55-vol: 74 | php_70-vol: 75 | composer_55-vol: 76 | composer_70-vol: 77 | es24-vol: 78 | -------------------------------------------------------------------------------- /templates/node.dockerfile.template: -------------------------------------------------------------------------------- 1 | {{if eq .Framework "meteor"}} 2 | FROM node:{{.Version}} 3 | 4 | # setup user home dir 5 | ENV USER node 6 | ENV HOME_DIR /home/$USER 7 | RUN mkdir -pv /home/$USER 8 | RUN chown $USER:$USER /home/$USER 9 | 10 | # setup application dir 11 | ENV APP_HOME /app 12 | RUN mkdir -pv $APP_HOME 13 | RUN chown $USER:$USER $APP_HOME 14 | 15 | # run next commands as user deamon 16 | USER $USER 17 | ENV HOME /home/$USER 18 | ENV PATH $PATH:$HOME/.meteor 19 | 20 | # install meteor (for building distribution) 21 | RUN curl -sL https://install.meteor.com/?release={{.FrameworkVersion}} | /bin/sh 22 | 23 | # setup temp dir for building meteor distribution 24 | USER root 25 | 26 | #install required packages (magick) 27 | RUN apt-get update 28 | RUN apt-get install apt-utils -y 29 | RUN apt-get install imagemagick libmagick++-dev libmagick++-6.q16-dev -y 30 | ENV PATH /usr/lib/x86_64-linux-gnu/ImageMagick-6.8.9/bin-Q16:$PATH 31 | 32 | ENV APP_TMP /tmp 33 | WORKDIR $APP_TMP 34 | COPY . $APP_TMP 35 | RUN chown -R $USER:$USER $APP_TMP 36 | USER $USER 37 | 38 | # set NPM stuff 39 | ENV NODE_ENV production 40 | ENV NPM_CONFIG_LOGLEVEL warn 41 | ENV ROOT_URL http://www.example.com 42 | 43 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 44 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 45 | # RUN npm config set strict-ssl false 46 | # RUN npm config set registry $CUSTOM_REGISTRY 47 | 48 | #install npm packages first 49 | RUN meteor npm install 50 | 51 | # build the distribution and deploy in app dir 52 | RUN meteor build --server-only --architecture=os.linux.x86_64 build 53 | RUN tar -xf build/tmp.tar.gz --strip-components=1 -C $APP_HOME 54 | 55 | # install NPM packages 56 | WORKDIR $APP_HOME 57 | RUN cd programs/server && npm install 58 | {{else}} 59 | FROM node:{{.Version}} 60 | 61 | ENV APP_HOME /app 62 | RUN mkdir -pv $APP_HOME 63 | WORKDIR $APP_HOME 64 | 65 | ADD . $APP_HOME 66 | 67 | ENV NODE_ENV production 68 | ENV NPM_CONFIG_LOGLEVEL warn 69 | 70 | # ADD CUSTOM REGISTRY HERE IF REQUIRED 71 | # ENV CUSTOM_REGISTRY https://registry.npmjs.org/ 72 | # RUN npm config set strict-ssl false 73 | # RUN npm config set registry $CUSTOM_REGISTRY 74 | 75 | RUN npm install 76 | {{end}} -------------------------------------------------------------------------------- /test/service_yml/service_to_kubes_1/expected/kubernetes.yml: -------------------------------------------------------------------------------- 1 | # Generated with <3 by Cloud66 2 | 3 | ####### CAKEPHP-SVC - Service ####### 4 | 5 | apiVersion: v1 6 | kind: Service 7 | metadata: 8 | name: cakephp-svc 9 | spec: 10 | ports: 11 | - name: 3000-expose 12 | port: 3000 13 | targetPort: 3000 14 | type: ClusterIP 15 | 16 | --- 17 | ####### CAKEPHP-SVN - Service ####### 18 | 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: cakephp-svn 23 | spec: 24 | ports: 25 | - name: 80-http-31111 26 | port: 80 27 | protocol: TCP 28 | targetPort: 8000 29 | nodePort: 31111 30 | - name: 3000-http-31112 31 | port: 3000 32 | protocol: TCP 33 | targetPort: 330 34 | nodePort: 31112 35 | - name: 443-http-31113 36 | port: 443 37 | protocol: TCP 38 | targetPort: 8443 39 | nodePort: 31113 40 | type: NodePort 41 | 42 | --- 43 | --- 44 | ####### CAKEPHP-DEPLOYMENT ####### 45 | apiVersion: extensions/v1beta1 46 | kind: Deployment 47 | metadata: 48 | name: cakephp-deployment 49 | spec: 50 | template: 51 | metadata: 52 | labels: 53 | app: cakephp 54 | spec: 55 | containers: 56 | - name: cakephp 57 | image: #INSERT REQUIRED IMAGE 58 | volumeMounts: 59 | - mountPath: /var/www/html/ 60 | name: /. 61 | - mountPath: /somewhere 62 | name: $(WIERD_ENV_VAR) 63 | - mountPath: other-place 64 | name: /somewhere 65 | readOnly: true 66 | env: 67 | - name: MYSQL_PASSWORD 68 | value: root 69 | ports: 70 | - name: 443-tcp 71 | protocol: TCP 72 | containerPort: 443 73 | 74 | --- 75 | ####### MYSQL-DEPLOYMENT ####### 76 | apiVersion: extensions/v1beta1 77 | kind: Deployment 78 | metadata: 79 | name: mysql-deployment 80 | spec: 81 | template: 82 | metadata: 83 | labels: 84 | app: mysql 85 | spec: 86 | containers: 87 | - name: mysql 88 | image: mysql:5.6 89 | volumeMounts: 90 | - mountPath: /var/lib/mysql 91 | name: /mysql-data 92 | env: 93 | - name: ENV 94 | value: some value 95 | 96 | -------------------------------------------------------------------------------- /definitions/service-yml/service.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | import ( 4 | "strings" 5 | ) 6 | 7 | type Service struct { 8 | GitUrl string `yaml:"git_url,omitempty"` 9 | GitBranch string `yaml:"git_branch,omitempty"` 10 | BuildRoot string `yaml:"build_root,omitempty"` 11 | BuildCommand string `yaml:"build_command,omitempty"` 12 | DockerfilePath string `yaml:"dockerfile_path,omitempty"` 13 | Image string `yaml:"image,omitempty"` 14 | Command string `yaml:"command,omitempty"` 15 | Requires []string `yaml:"requires,omitempty"` 16 | Tags []string `yaml:"tags,omitempty"` 17 | Ports Ports `yaml:"ports,omitempty"` 18 | EnvVars map[string]string `yaml:"env_vars,omitempty"` 19 | Volumes []string `yaml:"volumes,omitempty"` 20 | StopGrace int `yaml:"stop_grace,omitempty"` 21 | Constraints Constraints `yaml:"constraints,omitempty"` 22 | WorkDir string `yaml:"work_dir,omitempty"` 23 | Privileged bool `yaml:"privileged,omitempty"` 24 | PreStopCommand string `yaml:"pre_stop_command,omitempty"` 25 | PostStartCommand string `yaml:"post_start_command,omitempty"` 26 | DeployCommand string `yaml:"deploy_command,omitempty"` 27 | LogFolder string `yaml:"log_folder,omitempty"` 28 | DnsBehaviour string `yaml:"dns_behaviour,omitempty"` 29 | UseHabitus bool `yaml:"use_habitus,omitempty"` 30 | UseHabitusStep string `yaml:"use_habitus_step,omitempty"` 31 | Health string `yaml:"health,omitempty"` 32 | PreStartSignal string `yaml:"pre_start_signal,omitempty"` 33 | PreStopSequence string `yaml:"pre_stop_sequence,omitempty"` 34 | RestartOnDeploy bool `yaml:"restart_on_deploy,omitempty"` 35 | TrafficMatches TrafficMatches `yaml:"traffic_matches,omitempty"` 36 | } 37 | 38 | func (s Service) TagsToMap() map[string]string { 39 | result := make(map[string]string, len(s.Tags)) 40 | 41 | for _, tag := range s.Tags { 42 | pair := strings.SplitN(tag, ":", 2) 43 | result[pair[0]] = pair[1] 44 | } 45 | return result 46 | } 47 | -------------------------------------------------------------------------------- /test/ruby/rails_unicorn_mysql/src/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby '2.2.2' 3 | 4 | gem 'rails', '4.2.2' 5 | gem 'sass-rails', '~> 5.0' 6 | gem 'uglifier', '>= 1.3.0' 7 | gem 'coffee-rails', '~> 4.1.0' 8 | gem 'jquery-rails' 9 | gem 'jbuilder', '~> 2.0' 10 | gem 'bootstrap-sass' 11 | gem 'font-awesome-sass', '~> 4.3.0' 12 | gem 'devise' 13 | gem 'devise-i18n' 14 | gem 'devise_invitable' 15 | gem 'omniauth-facebook' 16 | gem 'koala' 17 | gem 'haml-rails' 18 | gem 'high_voltage' 19 | gem 'mysql2' 20 | gem 'pundit' 21 | gem 'simple_form' 22 | gem 'unicorn' 23 | gem 'unicorn-rails' 24 | gem 'summernote-rails' 25 | gem 'sentient_user' 26 | gem 'paper_trail' 27 | gem 'rolify' 28 | gem 'friendly_id' 29 | gem 'momentjs-rails' 30 | gem 'public_activity' 31 | gem 'crummy' 32 | gem 'refile', require: 'refile/rails' 33 | gem 'refile-mini_magick' 34 | gem 'impressionist' 35 | gem 'dotenv-rails' 36 | gem 'globalize', '~> 5.0.0' 37 | gem 'globalize-versioning', '~> 0.1.0' 38 | gem 'route_translator' 39 | gem 'lograge' 40 | gem 'peek', github: 'eitoball/peek', branch: 'update-gems' 41 | gem 'peek-git' 42 | gem 'peek-performance_bar' 43 | gem 'peek-mysql2' 44 | gem 'peek-gc' 45 | gem 'peek-rblineprof' 46 | gem 'pygments.rb', require: false 47 | gem 'intercom-rails' 48 | 49 | group :development do 50 | gem 'better_errors' 51 | gem 'foreman' 52 | gem 'guard-bundler' 53 | gem 'guard-rails' 54 | gem 'guard-rspec' 55 | gem 'guard-livereload', '~> 2.4', require: false 56 | gem 'html2haml' 57 | gem 'hub', require: nil 58 | gem 'quiet_assets' 59 | gem 'rails_layout' 60 | gem 'rb-fchange', require: false 61 | gem 'rb-fsevent', require: false 62 | gem 'rb-inotify', require: false 63 | gem 'spring-commands-rspec' 64 | gem 'pry-remote' 65 | gem 'xray-rails' 66 | end 67 | 68 | group :development, :test do 69 | gem 'factory_girl_rails' 70 | gem 'faker' 71 | gem 'pry-rails' 72 | gem 'pry-rescue' 73 | gem 'rspec-rails' 74 | gem 'rubocop' 75 | gem 'byebug' 76 | gem 'web-console', '~> 2.0' 77 | gem 'spring' 78 | gem 'i18n-tasks', '~> 0.8.3' 79 | gem 'bullet' 80 | end 81 | 82 | group :staging, :production do 83 | gem 'rails_12factor' 84 | gem 'sentry-raven', github: 'getsentry/raven-ruby' 85 | end 86 | 87 | group :test do 88 | gem 'capybara' 89 | gem 'database_cleaner' 90 | gem 'launchy' 91 | gem 'poltergeist' 92 | gem 'fuubar' 93 | gem 'codeclimate-test-reporter', require: nil 94 | gem 'simplecov', require: false 95 | gem 'shoulda-matchers' 96 | end 97 | -------------------------------------------------------------------------------- /definitions/docker-compose/service.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | type Service struct { 4 | Command Command `yaml:"command,omitempty"` 5 | Ports Ports `yaml:"ports,omitempty"` 6 | Build Build `yaml:"build,omitempty"` 7 | Image string `yaml:"image,omitempty"` 8 | Depends_on []string `yaml:"depends_on,omitempty"` 9 | Environment Environment `yaml:"environment,omitempty"` 10 | Deploy Deploy `yaml:"deploy,omitempty"` 11 | Volumes Volumes `yaml:"volumes,omitempty"` 12 | Stop_grace_period string `yaml:"stop_grace_period,omitempty"` 13 | Working_dir string `yaml:"working_dir,omitempty"` 14 | Privileged bool `yaml:"privileged,omitempty"` 15 | Labels map[string]string `yaml:"labels,omitempty"` 16 | Expose []int `yaml:"expose,omitempty"` 17 | EnvFile EnvFile `yaml:"env_file,omitempty"` 18 | CpuShares int `yaml:"cpu_shares,omitempty"` 19 | MemLimit string `yaml:"mem_limit,omitempty"` 20 | Links []string `yaml:"links,omitempty"` 21 | CapAdd []string `yaml:"cap_add,omitempty"` 22 | CapDrop []string `yaml:"cap_drop,omitempty"` 23 | Logging Logging `yaml:"logging,omitempty"` 24 | CgroupParent string `yaml:"cgroup_parent,omitempty"` 25 | ContainerName string `yaml:"container_name,omitempty"` 26 | Devices []string `yaml:"devices,omitempty"` 27 | Dns Dns `yaml:"dns,omitempty"` 28 | DnsSearch DnsSearch `yaml:"dns_search,omitempty"` 29 | Entrypoint Entrypoint `yaml:"entrypoint,omitempty"` 30 | ExternalLinks []string `yaml:"external_links,omitempty"` 31 | ExtraHosts []string `yaml:"extra_hosts,omitempty"` 32 | Isolation string `yaml:"isolation,omitempty"` 33 | Networks Networks `yaml:"networks,omitempty"` 34 | Pid string `yaml:"pid,omitempty"` 35 | Secrets Secrets `yaml:"secrets,omitempty"` 36 | SecurityOpt []string `yaml:"security_opt,omitempty"` 37 | StopSignal string `yaml:"stop_signal,omitempty"` 38 | Sysctls map[string]string `yaml:"sysctls,omitempty"` 39 | Tmpfs Tmpfs `yaml:"tmpfs,omitempty"` 40 | UsernsMode string `yaml:"userns_mode,omitempty"` 41 | Ulimits Ulimits `yaml:"ulimits,omitempty"` 42 | Healthcheck Healthcheck `yaml:"healthcheck,omitempty"` 43 | } 44 | -------------------------------------------------------------------------------- /detect.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | "github.com/cloud66-oss/starter/packs/compose-to-service-yml" 9 | "github.com/cloud66-oss/starter/packs/node" 10 | "github.com/cloud66-oss/starter/packs/php" 11 | "github.com/cloud66-oss/starter/packs/ruby" 12 | "github.com/cloud66-oss/starter/packs/service-yml-to-kubes" 13 | "os" 14 | "strings" 15 | ) 16 | 17 | func Detect(rootDir string) ([]packs.Pack, error) { 18 | ruby := ruby.Pack{} 19 | node := node.Pack{} 20 | php := php.Pack{} 21 | dockercompose := compose_to_service_yml.Pack{} 22 | serviceyml := service_yml_to_kubes.Pack{} 23 | detectors := []packs.Detector{dockercompose.Detector(), ruby.Detector(), node.Detector(), php.Detector(), serviceyml.Detector()} 24 | 25 | var packs []packs.Pack 26 | 27 | for _, d := range detectors { 28 | if d.Detect(rootDir) { 29 | packs = append(packs, d.GetPack()) 30 | common.PrintlnL0("Found %s application", d.GetPack().Name()) 31 | } 32 | } 33 | return packs, nil 34 | } 35 | 36 | func choosePack(detectedPacks []packs.Pack, noPrompt bool) (packs.Pack, error) { 37 | 38 | if len(detectedPacks) == 0 { 39 | 40 | return nil, fmt.Errorf("Could not detect any of the supported frameworks") 41 | 42 | } else if len(detectedPacks) > 1 { 43 | 44 | if noPrompt == false { 45 | 46 | common.PrintlnTitle("More than one framework detected. Please choose which of the following should be used:") 47 | 48 | for i := 0; i < len(detectedPacks); i++ { 49 | common.PrintlnTitle(strings.ToUpper(detectedPacks[i].Name())) 50 | } 51 | 52 | reader := bufio.NewReader(os.Stdin) 53 | var answer string 54 | answer, _ = reader.ReadString('\n') 55 | 56 | answer = strings.ToUpper(answer) 57 | 58 | for i := 0; i < len(detectedPacks); i++ { 59 | temp := strings.ToUpper(detectedPacks[i].Name()) + "\n" 60 | if answer == temp { 61 | return detectedPacks[i], nil 62 | } 63 | } 64 | return nil, fmt.Errorf("Starter was unable to match your answer") 65 | 66 | } else { 67 | 68 | common.PrintlnTitle("More than one framework detected! NoPrompt flag value is set to true.") 69 | 70 | for i := 0; i < len(detectedPacks); i++ { 71 | if detectedPacks[i].Name() == "docker-compose" { 72 | return detectedPacks[i], nil 73 | } 74 | } 75 | 76 | for i := 0; i < len(detectedPacks); i++ { 77 | if detectedPacks[i].Name() == "service.yml" { 78 | return detectedPacks[i], nil 79 | } 80 | } 81 | 82 | return nil, fmt.Errorf("Multiple frameworks detected. Unable to generate.") 83 | } 84 | } else { 85 | common.PrintlnTitle(detectedPacks[0].Name()) 86 | return detectedPacks[0], nil 87 | } 88 | 89 | return detectedPacks[0], nil 90 | } 91 | -------------------------------------------------------------------------------- /packs/python/pack.go: -------------------------------------------------------------------------------- 1 | package python 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | "github.com/cloud66-oss/starter/packs" 6 | ) 7 | 8 | type Pack struct { 9 | packs.PackBase 10 | Analysis *Analysis 11 | } 12 | 13 | const ( 14 | StencilTemplatePath = "" //TODO: still not implemented 15 | pythonGithubURL = "" //TODO: still not implemented 16 | ) 17 | 18 | func (p *Pack) Name() string { 19 | return "python" 20 | } 21 | 22 | func (p *Pack) LanguageVersion() string { 23 | return "x" 24 | } 25 | 26 | func (p *Pack) Detector() packs.Detector { 27 | return &Detector{PackElement: packs.PackElement{Pack: p}} 28 | } 29 | 30 | func (p *Pack) Analyze(rootDir string, environment string, shouldPrompt bool) error { 31 | var err error 32 | a := Analyzer{ 33 | AnalyzerBase: packs.AnalyzerBase{ 34 | PackElement: packs.PackElement{Pack: p}, 35 | RootDir: rootDir, 36 | ShouldPrompt: shouldPrompt, 37 | Environment: environment}} 38 | p.Analysis, err = a.Analyze() 39 | return err 40 | } 41 | 42 | func (p *Pack) WriteDockerfile(templateDir string, outputDir string, shouldPrompt bool) error { 43 | w := DockerfileWriter{ 44 | packs.DockerfileWriterBase{ 45 | PackElement: packs.PackElement{Pack: p}, 46 | TemplateWriterBase: packs.TemplateWriterBase{ 47 | TemplateDir: templateDir, 48 | OutputDir: outputDir, 49 | ShouldPrompt: shouldPrompt}}} 50 | return w.Write(p.Analysis.DockerfileContext) 51 | } 52 | 53 | func (p *Pack) WriteServiceYAML(templateDir string, outputDir string, shouldPrompt bool) error { 54 | w := ServiceYAMLWriter{ 55 | packs.ServiceYAMLWriterBase{ 56 | PackElement: packs.PackElement{Pack: p}, 57 | TemplateWriterBase: packs.TemplateWriterBase{ 58 | TemplateDir: templateDir, 59 | OutputDir: outputDir, 60 | ShouldPrompt: shouldPrompt}}} 61 | return w.Write(p.Analysis.ServiceYAMLContext) 62 | } 63 | 64 | func (p *Pack) WriteKubesConfig(outputDir string, shouldPrompt bool) error { 65 | common.PrintlnWarning("You can not generate a Kubernetes configuration file using this pack. Nothing to do.") 66 | return nil 67 | } 68 | 69 | func (p *Pack) GetMessages() []string { 70 | return p.Analysis.Messages.Items 71 | } 72 | 73 | func (p *Pack) StencilRepositoryPath() string { 74 | return StencilTemplatePath 75 | } 76 | 77 | func (p *Pack) PackGithubUrl() string { 78 | return pythonGithubURL 79 | } 80 | 81 | func (p *Pack) CreateSkycapFiles(outputDir string, templateDir string, branch string) error { 82 | common.PrintlnWarning("You can not generate the Skycap configuration files using this pack. Nothing to do.") 83 | return nil 84 | } 85 | 86 | func (p *Pack) FrameworkTag() string { 87 | return "" // Not supported 88 | } 89 | func (p *Pack) LanguageTag() string { 90 | return "" // Not supported 91 | } 92 | -------------------------------------------------------------------------------- /definitions/service-yml/utils.go: -------------------------------------------------------------------------------- 1 | package service_yml 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | ) 8 | 9 | func shortPortToLong(shortSyntax string) Port { 10 | var containerStr, httpStr, httpsStr string 11 | var i int 12 | 13 | if shortSyntax[0] == '"' { 14 | i = 1 15 | } else { 16 | i = 0 17 | } 18 | 19 | for ; i < len(shortSyntax); i++ { 20 | if shortSyntax[i] == ':' { 21 | break 22 | } else { 23 | containerStr = string(append([]byte(containerStr), shortSyntax[i])) 24 | } 25 | } 26 | 27 | for i = i + 1; i < len(shortSyntax); i++ { 28 | if shortSyntax[i] == ':' { 29 | break 30 | } else { 31 | httpStr = string(append([]byte(httpStr), shortSyntax[i])) 32 | } 33 | } 34 | 35 | for i = i + 1; i < len(shortSyntax); i++ { 36 | if shortSyntax[i] == '"' || shortSyntax[i] == '\n' { 37 | break 38 | } else { 39 | httpsStr = string(append([]byte(httpsStr), shortSyntax[i])) 40 | } 41 | } 42 | 43 | var container, http, https int 44 | var err error 45 | if containerStr != "" { 46 | container, err = strconv.Atoi(containerStr) 47 | CheckError(err) 48 | } else { 49 | container = 0 50 | } 51 | if httpStr != "" { 52 | http, err = strconv.Atoi(httpStr) 53 | CheckError(err) 54 | } else { 55 | http = 0 56 | } 57 | if httpsStr != "" { 58 | https, err = strconv.Atoi(httpsStr) 59 | CheckError(err) 60 | } else { 61 | https = 0 62 | } 63 | 64 | return Port{ 65 | Container: container, 66 | Http: http, 67 | Https: https, 68 | } 69 | } 70 | 71 | func stringToInt(strPort tempPort) Port { 72 | var port Port 73 | if strPort.Container != "" { 74 | if strPort.Container[0] == '"' { 75 | strPort.Container = strPort.Container[0:] 76 | strPort.Container = strPort.Container[:len(strPort.Container)-1] 77 | } 78 | port.Container, _ = strconv.Atoi(strPort.Container) 79 | 80 | } 81 | if strPort.Tcp != "" { 82 | if strPort.Tcp[0] == '"' { 83 | strPort.Tcp = strPort.Tcp[0:] 84 | strPort.Tcp = strPort.Tcp[:len(strPort.Tcp)-1] 85 | } 86 | port.Tcp, _ = strconv.Atoi(strPort.Tcp) 87 | 88 | } 89 | if strPort.Http != "" { 90 | if strPort.Http[0] == '"' { 91 | strPort.Http = strPort.Http[0:] 92 | strPort.Http = strPort.Http[:len(strPort.Http)-1] 93 | } 94 | port.Http, _ = strconv.Atoi(strPort.Http) 95 | 96 | } 97 | if strPort.Https != "" { 98 | if strPort.Https[0] == '"' { 99 | strPort.Https = strPort.Https[0:] 100 | strPort.Https = strPort.Https[:len(strPort.Https)-1] 101 | } 102 | port.Https, _ = strconv.Atoi(strPort.Https) 103 | 104 | } 105 | if strPort.Udp != "" { 106 | if strPort.Udp[0] == '"' { 107 | strPort.Udp = strPort.Udp[0:] 108 | strPort.Udp = strPort.Udp[:len(strPort.Udp)-1] 109 | } 110 | port.Udp, _ = strconv.Atoi(strPort.Udp) 111 | } 112 | return port 113 | } 114 | 115 | func CheckError(err error) { 116 | if err != nil { 117 | fmt.Println(err.Error()) 118 | os.Exit(1) 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /packs/template-writer-base.go: -------------------------------------------------------------------------------- 1 | package packs 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "os" 7 | "path/filepath" 8 | "strings" 9 | "text/template" 10 | 11 | "github.com/cloud66-oss/starter/common" 12 | ) 13 | 14 | const templateHeader = "# Generated by Cloud66 Starter" 15 | 16 | type TemplateWriterBase struct { 17 | TemplateDir string 18 | OutputDir string 19 | ShouldPrompt bool 20 | } 21 | 22 | func (w *TemplateWriterBase) WriteTemplate(templateName string, filename string, context interface{}) error { 23 | tmpl, err := template.ParseFiles(filepath.Join(w.TemplateDir, templateName)) 24 | if err != nil { 25 | return err 26 | } 27 | 28 | destFullPath := filepath.Join(w.OutputDir, filename) 29 | if !w.shouldOverwriteExistingFile(destFullPath) { 30 | newName := filename + ".old" 31 | err = os.Rename(destFullPath, filepath.Join(w.OutputDir, newName)) 32 | if err != nil { 33 | return err 34 | } 35 | common.PrintlnL2("Renaming %s to %s...", filename, newName) 36 | } 37 | 38 | destFile, err := os.Create(destFullPath) 39 | if err != nil { 40 | return err 41 | } 42 | defer func() { 43 | if err := destFile.Close(); err != nil { 44 | common.PrintlnError("Cannot close file %s due to: %s", filename, err.Error()) 45 | } 46 | }() 47 | 48 | common.PrintlnL2("Writing %s...", filename) 49 | err = tmpl.Execute(destFile, context) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | return w.prependToFile(destFullPath, templateHeader) 55 | } 56 | 57 | func (w *TemplateWriterBase) shouldOverwriteExistingFile(filename string) bool { 58 | if !common.FileExists(filename) { 59 | return true 60 | } 61 | isStarterTemplate := w.isStarterTemplate(filename) 62 | if isStarterTemplate { 63 | return true 64 | } 65 | if !w.ShouldPrompt { 66 | return isStarterTemplate 67 | } 68 | 69 | answer := "none" 70 | for answer != "o" && answer != "r" && answer != "" { 71 | common.PrintL1("%s cannot be written as it already exists. What to do? [o: overwrite, R: rename] ", filepath.Base(filename)) 72 | if _, err := fmt.Scanln(&answer); err != nil { 73 | return false 74 | } 75 | answer = strings.TrimSpace(strings.ToLower(answer)) 76 | } 77 | return answer == "o" 78 | } 79 | 80 | func (w *TemplateWriterBase) isStarterTemplate(filename string) bool { 81 | content, err := ioutil.ReadFile(filename) 82 | if err != nil { 83 | return false 84 | } 85 | 86 | lines := strings.Split(string(content), "\n") 87 | return len(lines) > 0 && lines[0] == templateHeader 88 | } 89 | 90 | func (w *TemplateWriterBase) prependToFile(filename string, text string) error { 91 | content, err := ioutil.ReadFile(filename) 92 | if err != nil { 93 | return err 94 | } 95 | 96 | lines := strings.Split(string(content), "\n") 97 | lines = append([]string{text}, lines...) 98 | 99 | file, err := os.Create(filename) 100 | if err != nil { 101 | return err 102 | } 103 | defer file.Close() 104 | _, err = file.WriteString(strings.Join(lines, "\n")) 105 | return err 106 | } 107 | -------------------------------------------------------------------------------- /test/node/express_rethinkdb/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "3ree", 3 | "version": "1.0.0", 4 | "description": "An example universal JS application written with the 3REE stack, React + Redux + RethinkDB + Express.", 5 | "main": "server.babel.js", 6 | "scripts": { 7 | "build:prod": "NODE_ENV=production webpack", 8 | "db-setup": "node dbSetup.babel.js", 9 | "lint": "eslint client server universal test server.js dbSetup.js", 10 | "start": "NODE_ENV=development node start-dev.js", 11 | "start:win": "set NODE_ENV=development&&node start-dev.js", 12 | "start:prod": "NODE_ENV=production node server.babel.js", 13 | "test": "./node_modules/karma/bin/karma start" 14 | }, 15 | "keywords": [ 16 | "react", 17 | "3ree", 18 | "rethinkdb", 19 | "redux", 20 | "webpack" 21 | ], 22 | "license": "MIT", 23 | "engines": { 24 | "node": ">=6.0.0", 25 | "npm": ">=3.8.6" 26 | }, 27 | "dependencies": { 28 | "bluebird": "3.1.x", 29 | "body-parser": "1.14.x", 30 | "classnames": "2.2.x", 31 | "config": "1.19.x", 32 | "ejs": "2.3.x", 33 | "express": "4.13.x", 34 | "history": "1.13.x", 35 | "moment": "2.11.x", 36 | "nib": "^1.1.x", 37 | "node-uuid": "1.4.x", 38 | "react": "15.0.x", 39 | "react-dom": "15.0.x", 40 | "react-redux": "4.4.x", 41 | "react-router": "2.4.x", 42 | "react-router-redux": "4.0.x", 43 | "redux": "3.5.x", 44 | "redux-logger": "2.6.x", 45 | "redux-thunk": "2.1.x", 46 | "rethinkdb": "2.3.x", 47 | "serve-static": "1.10.x", 48 | "socket.io": "1.4.x", 49 | "socket.io-client": "1.4.x", 50 | "superagent": "1.8.x", 51 | "xss": "0.2.x" 52 | }, 53 | "devDependencies": { 54 | "babel": "6.5.x", 55 | "babel-core": "6.8.x", 56 | "babel-eslint": "6.0.x", 57 | "babel-loader": "6.2.x", 58 | "babel-plugin-rewire": "1.0.0-rc-3", 59 | "babel-polyfill": "6.8.x", 60 | "babel-preset-es2015": "6.6.x", 61 | "babel-preset-react": "6.5.x", 62 | "babel-preset-react-hmre": "1.1.x", 63 | "babel-preset-stage-0": "6.5.x", 64 | "babel-runtime": "6.6.x", 65 | "babel-template": "6.8.x", 66 | "chai": "3.5.x", 67 | "css-loader": "0.23.x", 68 | "eslint": "2.9.x", 69 | "eslint-plugin-react": "5.1.x", 70 | "extract-text-webpack-plugin": "1.0.x", 71 | "karma": "0.13.x", 72 | "karma-chai": "0.1.x", 73 | "karma-chrome-launcher": "1.0.x", 74 | "karma-mocha": "1.0.x", 75 | "karma-mocha-reporter": "2.0.x", 76 | "karma-phantomjs-launcher": "1.0.x", 77 | "karma-sinon": "1.0.x", 78 | "karma-webpack": "1.7.x", 79 | "mocha": "2.4.x", 80 | "mocha-loader": "0.7.x", 81 | "nock": "8.0.x", 82 | "node-libs-browser": "1.0.x", 83 | "phantomjs-prebuilt": "2.1.x", 84 | "raw-loader": "0.5.x", 85 | "react-hot-loader": "1.3.x", 86 | "react-transform-hmr": "1.0.x", 87 | "redux-devtools": "3.3.x", 88 | "redux-devtools-dock-monitor": "1.1.x", 89 | "redux-devtools-log-monitor": "1.0.x", 90 | "redux-mock-store": "1.0.x", 91 | "sinon": "1.17.x", 92 | "style-loader": "0.13.x", 93 | "stylus": "0.54.x", 94 | "stylus-loader": "2.0.x", 95 | "webpack": "1.13.x", 96 | "webpack-dev-server": "1.14.x" 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/src/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' 4 | gem 'rails', '4.2.1' 5 | # Use postgresql as the database for Active Record 6 | gem 'pg' 7 | # Use SCSS for stylesheets 8 | gem 'sass-rails', '~> 5.0' 9 | # Use Uglifier as compressor for JavaScript assets 10 | gem 'uglifier', '>= 1.3.0' 11 | # Use CoffeeScript for .coffee assets and views 12 | gem 'coffee-rails', '~> 4.1.0' 13 | # See https://github.com/rails/execjs#readme for more supported runtimes 14 | # gem 'therubyracer', platforms: :ruby 15 | gem 'uuidtools' 16 | # Use jquery as the JavaScript library 17 | gem 'jquery-rails' 18 | # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks 19 | gem 'turbolinks' 20 | # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder 21 | gem 'jbuilder', '~> 2.0' 22 | # bundle exec rake doc:rails generates the API under doc/api. 23 | gem 'sdoc', '~> 0.4.0', group: :doc 24 | gem 'honeybadger', '~> 2.0' 25 | gem 'sidekiq' 26 | gem 'sidekiq-failures' 27 | gem 'seed_dump' 28 | gem 'devise' 29 | gem 'simple_token_authentication', '~> 1.0' 30 | gem 'fuzzy_match' 31 | 32 | gem 'activeadmin', github: 'activeadmin' 33 | gem 'redis' 34 | gem 'whenever', require: false 35 | gem 'sinatra', require: nil 36 | 37 | gem 'flattened_active_admin', '~> 0.0.3' 38 | 39 | gem 'inherited_resources' 40 | gem 'responders' 41 | 42 | gem 'ragamuffins' 43 | gem 'paginative' 44 | gem 'notify_user', github: 'Papercloud/notify_user' 45 | gem 'wolverine' 46 | 47 | # Use ActiveModel has_secure_password 48 | # gem 'bcrypt', '~> 3.1.7' 49 | 50 | gem 'foreman' 51 | # Use Unicorn as the app server 52 | gem 'unicorn' 53 | 54 | # Use Capistrano for deployment 55 | # gem 'capistrano-rails', group: :development 56 | 57 | # Generate controllers and doc(k)s 58 | gem 'harbourmaster' 59 | 60 | # Truncate html without breaking things 61 | gem 'truncate_html' 62 | 63 | # Only send emails to the places that we want. 64 | gem 'safety_mailer' 65 | 66 | group :development, :test do 67 | # Access an IRB console on exception pages or by using <%= console %> in views 68 | gem 'web-console', '~> 2.0' 69 | 70 | # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring 71 | gem 'spring' 72 | 73 | gem 'rspec-rails', '~> 3.2.1' 74 | gem 'factory_girl_rails' 75 | gem 'awesome_print' 76 | gem 'pry' 77 | gem 'guard' 78 | end 79 | 80 | group :development do 81 | gem 'overcommit' 82 | gem 'better_errors' 83 | gem 'validation_rage' 84 | gem 'quiet_assets' 85 | gem 'binding_of_caller' 86 | gem 'annotate' 87 | gem 'guard-livereload', '~> 2.4', require: false 88 | gem 'restkit_generators', github: 'Papercloud/restkit_generators', branch: 'develop' 89 | gem 'letter_opener' 90 | end 91 | 92 | gem 'rubocop', require: false 93 | 94 | group :test do 95 | gem 'database_cleaner' 96 | gem 'spring-commands-rspec' 97 | gem 'vcr' 98 | gem 'shoulda-matchers', require: false 99 | gem 'timecop' 100 | gem 'bullet' 101 | gem 'mock_redis' 102 | gem 'rspec-sidekiq' 103 | end 104 | -------------------------------------------------------------------------------- /definitions/docker-compose/utils.go: -------------------------------------------------------------------------------- 1 | package docker_compose 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "strconv" 7 | "strings" 8 | "unicode" 9 | ) 10 | 11 | func getKeyValue(line string) (string, string) { 12 | var key, value string 13 | var k int 14 | for k = 0; k < len(line); k++ { 15 | if !unicode.IsSpace(rune(line[k])) && line[k] != '"' { 16 | break 17 | } 18 | } 19 | for ; k < len(line); k++ { 20 | if line[k] == '=' || line[k] == '"' { 21 | break 22 | } else { 23 | key = string(append([]byte(key), line[k])) 24 | } 25 | } 26 | if k < len(line)-2 { 27 | if line[k+1] == '=' && line[k+2] == '"' { 28 | k = k + 2 29 | } else if (line[k+1] == '=' && line[k+2] != '"') || (line[k+1] == '"') { 30 | k = k + 1 31 | } 32 | for k = k + 1; k < len(line); k++ { 33 | if line[k] == '\n' || line[k] == '"' { 34 | break 35 | } else { 36 | value = string(append([]byte(value), line[k])) 37 | } 38 | } 39 | } 40 | 41 | return key, value 42 | } 43 | 44 | func shortPortToLong(str string) Port { 45 | var port Port 46 | var i int 47 | var host, container, protocol string 48 | if str[0] == '"' { 49 | i = 1 50 | } else { 51 | i = 0 52 | } 53 | for ; i < len(str); i++ { 54 | if !unicode.IsDigit(rune(str[i])) { 55 | break 56 | } else { 57 | host = string(append([]byte(host), str[i])) 58 | } 59 | } 60 | for i = i + 1; i < len(str); i++ { 61 | if !unicode.IsDigit(rune(str[i])) { 62 | break 63 | } else { 64 | container = string(append([]byte(container), str[i])) 65 | } 66 | } 67 | protocol = "tcp" 68 | if i < len(str)-1 { 69 | if strings.Contains(str[i:], "udp") { 70 | protocol = "udp" 71 | } 72 | } 73 | var target, published int 74 | var err error 75 | 76 | if container != "" { 77 | target, err = strconv.Atoi(container) 78 | CheckError(err) 79 | } 80 | if host != "" { 81 | published, err = strconv.Atoi(host) 82 | CheckError(err) 83 | } 84 | 85 | port = Port{ 86 | Protocol: protocol, 87 | Target: target, 88 | Published: published, 89 | } 90 | 91 | return port 92 | } 93 | 94 | func shortSecretToLong(str string) Secret { 95 | var secret Secret 96 | secret.Source = str 97 | return secret 98 | } 99 | 100 | func shortVolumeToLong(str string) Volume { 101 | var volume Volume 102 | var i int 103 | var source, target string 104 | var readOnly bool 105 | 106 | if str[0] == '"' { 107 | i = 1 108 | } else { 109 | i = 0 110 | } 111 | for ; i < len(str); i++ { 112 | if str[i] == ':' { 113 | break 114 | } else { 115 | source = string(append([]byte(source), str[i])) 116 | } 117 | } 118 | for i = i + 1; i < len(str); i++ { 119 | if str[i] == ':' || str[i] == '\n' || str[i] == '"' { 120 | break 121 | } else { 122 | target = string(append([]byte(target), str[i])) 123 | } 124 | } 125 | if i < len(str)-2 { 126 | if strings.Contains(str[i+1:], "ro") { 127 | readOnly = true 128 | } 129 | } 130 | volume = Volume{ 131 | Type: "volume", 132 | Source: source, 133 | Target: target, 134 | ReadOnly: readOnly, 135 | } 136 | return volume 137 | } 138 | 139 | func CheckError(err error) { 140 | if err != nil { 141 | fmt.Println(err.Error()) 142 | os.Exit(1) 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /definitions/kubernetes/utils.go: -------------------------------------------------------------------------------- 1 | package kubernetes 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "sort" 7 | "strconv" 8 | "strings" 9 | 10 | "gopkg.in/yaml.v2" 11 | ) 12 | 13 | func composeWriter(file []byte, deployments []KubesDeployment, kubesServices []KubesService) []byte { 14 | var keys []string 15 | for _, k := range kubesServices { 16 | keys = append(keys, k.Metadata.Name) 17 | } 18 | sort.Strings(keys) 19 | indexPort := 31111 //magic number to hope it will not overlap with other unrelated ports 20 | 21 | for _, k := range keys { 22 | for i := 0; i < len(kubesServices); i++ { 23 | if kubesServices[i].Metadata.Name == k { 24 | if len(kubesServices[i].Spec.Ports) > 0 { 25 | for v, port := range kubesServices[i].Spec.Ports { 26 | if port.NodePort != 0 { 27 | port.NodePort = indexPort 28 | port.Name = port.Name[:len(port.Name)-5] + strconv.Itoa(indexPort) 29 | indexPort++ 30 | kubesServices[i].Spec.Ports[v] = port 31 | } 32 | } 33 | } 34 | fileServices, err := yaml.Marshal(kubesServices[i]) 35 | CheckError(err) 36 | file = []byte(string(file) + "####### " + strings.ToUpper(string(kubesServices[i].Metadata.Name)) + " - Service #######\n" + "\n" + string(finalFormat(fileServices)) + "---\n") 37 | break 38 | } 39 | } 40 | } 41 | 42 | keys = []string{} 43 | for _, k := range deployments { 44 | keys = append(keys, k.Metadata.Name) 45 | } 46 | sort.Strings(keys) 47 | 48 | for _, k := range keys { 49 | for i := 0; i < len(deployments); i++ { 50 | if deployments[i].Metadata.Name == k { 51 | fileDeployments, err := yaml.Marshal(deployments[i]) 52 | CheckError(err) 53 | file = []byte(string(file) + "---\n####### " + strings.ToUpper(string(deployments[i].Metadata.Name)) + " #######\n" + string(finalFormat(fileDeployments))) 54 | break 55 | } 56 | } 57 | } 58 | return file 59 | } 60 | 61 | func finalFormat(file []byte) string { 62 | finalFormat := "" 63 | 64 | lines := strings.Split(string(file), "\n") 65 | 66 | for i := 0; i < len(lines); i++ { 67 | if strings.Contains(lines[i], "_env") { 68 | for j := 0; j < len(lines[i])-4; j++ { 69 | if lines[i][j] == '_' && lines[i][j+1] == 'e' && lines[i][j+2] == 'n' && lines[i][j+3] == 'v' { 70 | lines[i] = lines[i][:j] + "$" + lines[i][j+4:] 71 | } 72 | } 73 | } 74 | 75 | // handle empty value for env_vars 76 | if strings.Contains(lines[i], "value: ") && strings.Contains(lines[i], "\"\"") { 77 | for j := 0; j < len(lines[i]); j++ { 78 | if lines[i][j] == '"' { 79 | lines[i] = lines[i][:j] 80 | break 81 | } 82 | } 83 | } 84 | 85 | //format comment for empty image field 86 | if strings.Contains(lines[i], "image: '#") { 87 | for j := 0; j < len(lines[i]); j++ { 88 | if string(lines[i][j]) == "'" && j < len(lines[i])-1 { 89 | lines[i] = lines[i][:j] + " " + lines[i][j+1:] 90 | } else if string(lines[i][j]) == "'" { 91 | lines[i] = lines[i][:j] 92 | } 93 | } 94 | } 95 | 96 | finalFormat = finalFormat + lines[i] + "\n" 97 | } 98 | 99 | return finalFormat 100 | } 101 | 102 | func CheckError(err error) { 103 | if err != nil { 104 | fmt.Println(err.Error()) 105 | os.Exit(1) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /common/utils-git.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "os/exec" 7 | "path" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | func HasGit(dir string) bool { 13 | _, err := GitRootDir(dir) 14 | if err != nil { 15 | return false 16 | } 17 | return true 18 | } 19 | 20 | func LocalGitBranch(dir string) string { 21 | gitRootDir, err := GitRootDir(dir) 22 | if err != nil { 23 | return "" 24 | } 25 | 26 | b, err := exec.Command("git", "--git-dir", fmt.Sprintf("%s/.git", gitRootDir), "name-rev", "--name-only", "HEAD").Output() 27 | if err != nil { 28 | return "" 29 | } 30 | return strings.TrimSpace(strings.Replace(string(b), "https://", "http://", -1)) 31 | } 32 | 33 | func AddFile(dir string, file string) error { 34 | gitRootDir, err := GitRootDir(dir) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | _, err = exec.Command("git", "--git-dir", fmt.Sprintf("%s/.git", gitRootDir), "add", file).Output() 40 | if err != nil { 41 | return err 42 | } 43 | 44 | return nil 45 | } 46 | 47 | func Commit(dir string, message string) error { 48 | gitRootDir, err := GitRootDir(dir) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | _, err = exec.Command("git", "--git-dir", fmt.Sprintf("%s/.git", gitRootDir), "commit", "-m", fmt.Sprintf("'%s'", message)).Output() 54 | if err != nil { 55 | return err 56 | } 57 | 58 | return nil 59 | } 60 | 61 | func RemoteGitUrl(dir string) string { 62 | gitRootDir, err := GitRootDir(dir) 63 | if err != nil { 64 | return "" 65 | } 66 | 67 | b, err := exec.Command("git", "--git-dir", fmt.Sprintf("%s/.git", gitRootDir), "config", "remote.origin.url").Output() 68 | if err != nil { 69 | return "" 70 | } 71 | return strings.TrimSpace(strings.Replace(string(b), "https://", "http://", -1)) 72 | } 73 | 74 | func GitRootDir(dir string) (string, error) { 75 | cmd := exec.Command("git", "rev-parse", "--show-toplevel") 76 | cmd.Dir = dir 77 | b, err := cmd.Output() 78 | if err != nil { 79 | return "", err 80 | } else { 81 | return strings.TrimSpace(string(b)), err 82 | } 83 | } 84 | 85 | func PathRelativeToGitRoot(dirPath string) (string, error) { 86 | dirPath, err := filepath.Abs(dirPath) 87 | if err != nil { 88 | return "", err 89 | } 90 | dir, err := os.Open(dirPath) 91 | if err != nil { 92 | return "", err 93 | } 94 | defer dir.Close() 95 | dirInfo, err := dir.Stat() 96 | if err != nil { 97 | return "", err 98 | } 99 | 100 | gitRootDir, err := GitRootDir(dirPath) 101 | if err != nil { 102 | return "", err 103 | } 104 | 105 | root, err := os.Open(gitRootDir) 106 | if err != nil { 107 | return "", err 108 | } 109 | defer root.Close() 110 | rootInfo, err := root.Stat() 111 | if err != nil { 112 | return "", err 113 | } 114 | 115 | relativePath := "" 116 | for !os.SameFile(rootInfo, dirInfo) { 117 | relativePath = path.Base(dirPath) + "/" + relativePath 118 | dirPath = path.Dir(dirPath) 119 | dir, err = os.Open(dirPath) 120 | if err != nil { 121 | return "", err 122 | } 123 | defer dir.Close() 124 | dirInfo, err = dir.Stat() 125 | if err != nil { 126 | return "", err 127 | } 128 | } 129 | 130 | if relativePath == "" { 131 | relativePath = "." 132 | } 133 | 134 | return relativePath, nil 135 | } 136 | -------------------------------------------------------------------------------- /common/utils-template.go: -------------------------------------------------------------------------------- 1 | package common 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "fmt" 7 | "io" 8 | "net/http" 9 | "os" 10 | "path/filepath" 11 | "strings" 12 | "time" 13 | ) 14 | 15 | type DownloadFile struct { 16 | URL string `json:"url"` 17 | Name string `json:"name"` 18 | } 19 | 20 | type TemplateDefinition struct { 21 | Version string `json:"version"` 22 | Dockerfiles []DownloadFile `json:"dockerfiles"` 23 | ServiceYmls []DownloadFile `json:"service-ymls"` 24 | DockerComposeYmls []DownloadFile `json:"docker-compose-ymls"` 25 | BundleManifest []DownloadFile `json:"bundle-manifest-jsons"` 26 | } 27 | 28 | func Fetch(url string, mod *time.Time) (io.ReadCloser, error) { 29 | PrintlnL2("Downloading from %s", url) 30 | req, err := http.NewRequest("GET", url, nil) 31 | if err != nil { 32 | return nil, err 33 | } 34 | if mod != nil { 35 | req.Header.Add("If-Modified-Since", mod.Format(http.TimeFormat)) 36 | } 37 | resp, err := http.DefaultClient.Do(req) 38 | if err != nil { 39 | return nil, err 40 | } 41 | if mod != nil && resp.StatusCode == 304 { 42 | return nil, errors.New("item moved") 43 | } 44 | if resp.StatusCode != 200 { 45 | err := fmt.Errorf("bad http status from %s: %v", url, resp.Status) 46 | return nil, err 47 | } 48 | if s := resp.Header.Get("Last-Modified"); mod != nil && s != "" { 49 | t, err := time.Parse(http.TimeFormat, s) 50 | if err == nil { 51 | *mod = t 52 | } 53 | } 54 | return resp.Body, nil 55 | } 56 | 57 | func FetchJSON(url string, mod *time.Time, v interface{}) error { 58 | r, err := Fetch(url, mod) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | defer r.Close() 64 | return json.NewDecoder(r).Decode(v) 65 | } 66 | 67 | func DownloadTemplates(tempDir string, td TemplateDefinition, templatePath string, flagBranch string) error { 68 | err := DownloadSingleFile(tempDir, DownloadFile{URL: strings.Replace(templatePath, "{{.branch}}", flagBranch, -1), Name: "templates.json"}, flagBranch) 69 | if err != nil { 70 | return err 71 | } 72 | 73 | for _, temp := range td.Dockerfiles { 74 | err := DownloadSingleFile(tempDir, temp, flagBranch) 75 | if err != nil { 76 | return err 77 | } 78 | } 79 | 80 | for _, temp := range td.ServiceYmls { 81 | err := DownloadSingleFile(tempDir, temp, flagBranch) 82 | if err != nil { 83 | return err 84 | } 85 | } 86 | 87 | for _, temp := range td.DockerComposeYmls { 88 | err := DownloadSingleFile(tempDir, temp, flagBranch) 89 | if err != nil { 90 | return err 91 | } 92 | } 93 | 94 | for _, temp := range td.BundleManifest { 95 | err := DownloadSingleFile(tempDir, temp, flagBranch) 96 | if err != nil { 97 | return err 98 | } 99 | } 100 | 101 | return nil 102 | } 103 | 104 | func DownloadSingleFile(tempDir string, temp DownloadFile, flagBranch string) error { 105 | r, err := Fetch(strings.Replace(temp.URL, "{{.branch}}", flagBranch, -1), nil) 106 | if err != nil { 107 | return err 108 | } 109 | defer r.Close() 110 | 111 | output, err := os.Create(filepath.Join(tempDir, temp.Name)) 112 | if err != nil { 113 | return err 114 | } 115 | defer output.Close() 116 | 117 | _, err = io.Copy(output, r) 118 | if err != nil { 119 | return err 120 | } 121 | 122 | return nil 123 | } 124 | -------------------------------------------------------------------------------- /packs/php/analyzer.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import ( 4 | "path/filepath" 5 | 6 | "github.com/cloud66-oss/starter/common" 7 | "github.com/cloud66-oss/starter/packs" 8 | ) 9 | 10 | type Analyzer struct { 11 | packs.AnalyzerBase 12 | ComposerJSON string 13 | } 14 | 15 | func (a *Analyzer) Analyze() (*Analysis, error) { 16 | a.ComposerJSON = filepath.Join(a.RootDir, "composer.json") 17 | gitURL, gitBranch, buildRoot, err := a.ProjectMetadata() 18 | if err != nil { 19 | return nil, err 20 | } 21 | version := a.FindVersion() 22 | dbs := a.ConfirmDatabases(a.FindDatabases()) 23 | envVars := a.EnvVars() 24 | packages := a.GuessPackages() 25 | framework := a.GuessFramework() 26 | a.CheckNotSupportedPackages(packages) 27 | 28 | services, err := a.AnalyzeServices(a, envVars, gitBranch, gitURL, buildRoot) 29 | 30 | // inject all the services with the databases used in the infrastructure 31 | for _, service := range services { 32 | service.Databases = dbs 33 | } 34 | 35 | if err != nil { 36 | return nil, err 37 | } 38 | 39 | analysis := &Analysis{ 40 | AnalysisBase: packs.AnalysisBase{ 41 | PackName: a.GetPack().Name(), 42 | GitBranch: gitBranch, 43 | GitURL: gitURL, 44 | Framework: framework, 45 | Messages: a.Messages}, 46 | DockerComposeYAMLContext: &DockerComposeYAMLContext{packs.DockerComposeYAMLContextBase{Services: services, Dbs: dbs}}, 47 | ServiceYAMLContext: &ServiceYAMLContext{packs.ServiceYAMLContextBase{Services: services, Dbs: dbs}}, 48 | DockerfileContext: &DockerfileContext{packs.DockerfileContextBase{Version: version, Packages: packages}}} 49 | return analysis, nil 50 | } 51 | 52 | func (a *Analyzer) FillServices(services *[]*common.Service) error { 53 | if len(*services) == 0 { 54 | var service *common.Service 55 | service = &common.Service{Name: "web"} 56 | service.Ports = []*common.PortMapping{common.NewPortMapping()} 57 | service.Command = "apache2-foreground" 58 | service.Ports[0].Container = "80" 59 | *services = append(*services, service) 60 | } 61 | return nil 62 | } 63 | 64 | func (a *Analyzer) HasPackage(pack string) bool { 65 | hasFound, _ := common.GetDependencyVersion(a.ComposerJSON, pack) 66 | return hasFound 67 | } 68 | 69 | func (a *Analyzer) GuessFramework() string { 70 | if runsLaravel, _ := common.GetFramework(a.ComposerJSON, "laravel/framework"); runsLaravel { 71 | return "laravel" 72 | } 73 | return "" 74 | } 75 | 76 | func (a *Analyzer) GuessPackages() *common.Lister { 77 | packages := common.NewLister() 78 | return packages 79 | } 80 | 81 | func (a *Analyzer) FindVersion() string { 82 | foundNode, phpVersion := common.GetPHPVersion(a.ComposerJSON) 83 | return a.ConfirmVersion(foundNode, phpVersion, "latest") 84 | } 85 | 86 | func (a *Analyzer) FindDatabases() []common.Database { 87 | dbs := []common.Database{} 88 | if hasMysql, _ := common.GetPHPDatabase(a.ComposerJSON, "mysql"); hasMysql { 89 | dbs = append(dbs, common.Database{Name: "mysql", DockerImage: "mysql"}) 90 | } 91 | //if hasPostgres, _ := common.GetPHPDatabase(a.ComposerJSON, "pgsql"); hasPostgres { 92 | // dbs = append(dbs, common.Database{Name: "postgres", DockerImage: "postgres"}) 93 | //} 94 | return dbs 95 | } 96 | 97 | func (a *Analyzer) EnvVars() []*common.EnvVar { 98 | return []*common.EnvVar{} 99 | } 100 | -------------------------------------------------------------------------------- /packs/service-yml-to-kubes/pack.go: -------------------------------------------------------------------------------- 1 | package service_yml_to_kubes 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | "github.com/cloud66-oss/starter/definitions/service-yml" 6 | "github.com/cloud66-oss/starter/packs" 7 | "github.com/cloud66-oss/starter/transform" 8 | ) 9 | 10 | type Pack struct { 11 | packs.PackBase 12 | Analysis *Analysis 13 | } 14 | 15 | const ( 16 | StencilTemplatePath = "" //TODO: still not implemented 17 | serviceGithubURL = "" //TODO: still not implemented 18 | ) 19 | 20 | func (p *Pack) Name() string { 21 | return "service.yml" 22 | } 23 | 24 | func (p *Pack) LanguageVersion() string { 25 | return p.Analysis.LanguageVersion 26 | } 27 | 28 | func (p *Pack) FilesToBeAnalysed() []string { 29 | return []string{"service.yml"} 30 | } 31 | 32 | func (p *Pack) Framework() string { 33 | return "" 34 | } 35 | 36 | func (p *Pack) FrameworkVersion() string { 37 | return "" 38 | } 39 | 40 | func (p *Pack) GetSupportedLanguageVersions() []string { 41 | return nil 42 | } 43 | 44 | func (p *Pack) SetSupportedLanguageVersions(versions []string) { 45 | 46 | } 47 | 48 | func (p *Pack) Detector() packs.Detector { 49 | return &Detector{PackElement: packs.PackElement{Pack: p}} 50 | } 51 | 52 | func (p *Pack) Analyze(rootDir string, environment string, shouldPrompt bool, git_repo string, git_branch string) error { 53 | var err error 54 | a := Analyzer{ 55 | AnalyzerBase: packs.AnalyzerBase{ 56 | PackElement: packs.PackElement{Pack: p}, 57 | RootDir: rootDir, 58 | ShouldPrompt: shouldPrompt, 59 | GitURL: git_repo, 60 | GitBranch: git_branch, 61 | Environment: environment}} 62 | p.Analysis, err = a.Analyze() 63 | return err 64 | } 65 | 66 | func (p *Pack) WriteDockerfile(templateDir string, outputDir string, shouldPrompt bool) error { 67 | 68 | //common.PrintlnWarning("You can not generate a Dockerfile using this pack. Nothing to do.") 69 | return nil 70 | } 71 | 72 | func (p *Pack) WriteKubesConfig(outputDir string, shouldPrompt bool) error { 73 | 74 | serviceYmlBase := service_yml.ServiceYml{} 75 | serviceYmlBase.UnmarshalFromFile(outputDir + "/service.yml") 76 | 77 | s := transform.ServiceYmlTransformer{Base: serviceYmlBase} 78 | 79 | kubernetes := s.ToKubernetes() 80 | kubernetes.MarshalToFile(outputDir + "/kubernetes.yml") 81 | 82 | return nil 83 | } 84 | 85 | func (p *Pack) WriteDockerComposeYAML(templateDir string, outputDir string, shouldPrompt bool) error { 86 | common.PrintlnWarning("You can not generate a docker-compose.yml using this pack. Nothing to do.") 87 | return nil 88 | } 89 | func (p *Pack) WriteServiceYAML(templateDir string, outputDir string, shouldPrompt bool) error { 90 | common.PrintlnWarning("There is already an existing service.yml. Nothing to do.") 91 | return nil 92 | } 93 | 94 | func (p *Pack) GetMessages() []string { 95 | return []string{} 96 | } 97 | 98 | func (p *Pack) GetDatabases() []string { 99 | return []string{} 100 | } 101 | 102 | func (p *Pack) GetStartCommands() []string { 103 | return []string{} 104 | } 105 | 106 | func (p *Pack) StencilRepositoryPath() string { 107 | return StencilTemplatePath 108 | } 109 | 110 | func (p *Pack) PackGithubUrl() string { 111 | return serviceGithubURL 112 | } 113 | 114 | func (p *Pack) CreateSkycapFiles(outputDir string, templateDir string, branch string) error { 115 | common.PrintlnWarning("You can not generate the Skycap configuration files using this pack. Nothing to do.") 116 | return nil 117 | } 118 | 119 | func (p *Pack) FrameworkTag() string { 120 | return "" // Not supported 121 | } 122 | func (p *Pack) LanguageTag() string { 123 | return "" // Not supported 124 | } 125 | -------------------------------------------------------------------------------- /test/node/express_mysql_pg/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ghost", 3 | "version": "0.10.0", 4 | "description": "Just a blogging platform.", 5 | "author": "Ghost Foundation", 6 | "homepage": "http://ghost.org", 7 | "keywords": [ 8 | "ghost", 9 | "blog", 10 | "cms" 11 | ], 12 | "repository": { 13 | "type": "git", 14 | "url": "git://github.com/TryGhost/Ghost.git" 15 | }, 16 | "bugs": "https://github.com/TryGhost/Ghost/issues", 17 | "contributors": "https://github.com/TryGhost/Ghost/graphs/contributors", 18 | "license": "MIT", 19 | "main": "./core/index", 20 | "scripts": { 21 | "preinstall": "node core/server/utils/npm/preinstall.js", 22 | "start": "node index", 23 | "test": "grunt validate --verbose" 24 | }, 25 | "engines": { 26 | "node": "~0.10.0 || ~0.12.0 || ^4.2.0" 27 | }, 28 | "dependencies": { 29 | "amperize": "https://github.com/AileenCGN/amperize/tarball/fixed-layout-for-small-images", 30 | "archiver": "1.0.1", 31 | "bcryptjs": "2.3.0", 32 | "bluebird": "3.4.1", 33 | "body-parser": "1.15.2", 34 | "bookshelf": "0.10.0", 35 | "chalk": "1.1.3", 36 | "cheerio": "0.20.0", 37 | "compression": "1.6.2", 38 | "connect-slashes": "1.3.1", 39 | "cookie-session": "1.2.0", 40 | "cors": "2.7.1", 41 | "csv-parser": "1.9.3", 42 | "downsize": "0.0.8", 43 | "express": "4.14.0", 44 | "express-hbs": "1.0.2", 45 | "extract-zip": "1.5.0", 46 | "fs-extra": "0.30.0", 47 | "ghost-gql": "0.0.5", 48 | "glob": "5.0.15", 49 | "gscan": "0.0.11", 50 | "html-to-text": "2.1.3", 51 | "image-size": "0.5.0", 52 | "intl": "1.2.4", 53 | "intl-messageformat": "1.3.0", 54 | "jsonpath": "0.2.6", 55 | "knex": "0.20.1", 56 | "lodash": "4.15.0", 57 | "moment": "2.14.1", 58 | "moment-timezone": "0.5.5", 59 | "morgan": "1.7.0", 60 | "multer": "1.2.0", 61 | "netjet": "1.1.2", 62 | "node-uuid": "1.4.7", 63 | "nodemailer": "0.7.1", 64 | "oauth2orize": "1.5.0", 65 | "passport": "0.3.2", 66 | "passport-http-bearer": "1.0.1", 67 | "passport-oauth2-client-password": "0.1.2", 68 | "path-match": "1.2.4", 69 | "rss": "1.2.1", 70 | "sanitize-html": "1.13.0", 71 | "semver": "5.3.0", 72 | "showdown-ghost": "0.3.6", 73 | "sqlite3": "3.1.4", 74 | "superagent": "2.2.0", 75 | "unidecode": "0.1.8", 76 | "validator": "5.5.0", 77 | "xml": "1.0.1" 78 | }, 79 | "optionalDependencies": { 80 | "mysql": "2.1.1", 81 | "pg": "4.1.1" 82 | }, 83 | "devDependencies": { 84 | "gh-contrib-list": "0.1.2", 85 | "git-wrapper": "0.1.1", 86 | "grunt": "1.0.1", 87 | "grunt-bg-shell": "2.3.3", 88 | "grunt-cli": "1.2.0", 89 | "grunt-contrib-clean": "1.0.0", 90 | "grunt-contrib-compress": "1.3.0", 91 | "grunt-contrib-copy": "1.0.0", 92 | "grunt-contrib-jshint": "1.0.0", 93 | "grunt-contrib-uglify": "2.0.0", 94 | "grunt-contrib-watch": "1.0.0", 95 | "grunt-docker": "0.0.11", 96 | "grunt-express-server": "0.5.3", 97 | "grunt-jscs": "3.0.1", 98 | "grunt-mocha-cli": "2.1.0", 99 | "grunt-mocha-istanbul": "5.0.2", 100 | "grunt-shell": "1.3.1", 101 | "grunt-subgrunt": "1.2.0", 102 | "grunt-update-submodules": "0.4.1", 103 | "istanbul": "0.4.4", 104 | "matchdep": "1.0.1", 105 | "mocha": "3.0.2", 106 | "nock": "8.0.0", 107 | "rewire": "2.5.2", 108 | "should": "11.1.0", 109 | "should-http": "0.0.4", 110 | "sinon": "1.17.5", 111 | "supertest": "1.2.0", 112 | "tmp": "0.0.28" 113 | }, 114 | "greenkeeper": { 115 | "ignore": [ 116 | "glob", 117 | "mysql", 118 | "nodemailer", 119 | "pg", 120 | "showdown-ghost" 121 | ] 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /packs/compose-to-service-yml/pack.go: -------------------------------------------------------------------------------- 1 | package compose_to_service_yml 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | "github.com/cloud66-oss/starter/definitions/docker-compose" 6 | "github.com/cloud66-oss/starter/packs" 7 | "github.com/cloud66-oss/starter/transform" 8 | ) 9 | 10 | type Pack struct { 11 | packs.PackBase 12 | Analysis *Analysis 13 | } 14 | 15 | const ( 16 | StencilTemplatePath = "" //TODO: still not implemented 17 | dockerGithubUrl = "" //TODO: still not implemented 18 | ) 19 | 20 | func (p *Pack) Name() string { 21 | return "docker-compose" 22 | } 23 | 24 | func (p *Pack) LanguageVersion() string { 25 | return p.Analysis.LanguageVersion 26 | } 27 | 28 | func (p *Pack) FilesToBeAnalysed() []string { 29 | return []string{"docker-compose.yml"} 30 | } 31 | 32 | func (p *Pack) Framework() string { 33 | return "" 34 | } 35 | 36 | func (p *Pack) FrameworkVersion() string { 37 | return "" 38 | } 39 | 40 | func (p *Pack) GetSupportedLanguageVersions() []string { 41 | return nil 42 | } 43 | 44 | func (p *Pack) SetSupportedLanguageVersions(versions []string) { 45 | 46 | } 47 | 48 | func (p *Pack) Detector() packs.Detector { 49 | return &Detector{PackElement: packs.PackElement{Pack: p}} 50 | } 51 | 52 | func (p *Pack) Analyze(rootDir string, environment string, shouldPrompt bool, git_repo string, git_branch string) error { 53 | var err error 54 | a := Analyzer{ 55 | AnalyzerBase: packs.AnalyzerBase{ 56 | PackElement: packs.PackElement{Pack: p}, 57 | RootDir: rootDir, 58 | ShouldPrompt: shouldPrompt, 59 | GitURL: git_repo, 60 | GitBranch: git_branch, 61 | Environment: environment}} 62 | p.Analysis, err = a.Analyze() 63 | return err 64 | } 65 | 66 | func (p *Pack) WriteDockerfile(templateDir string, outputDir string, shouldPrompt bool) error { 67 | 68 | common.PrintlnWarning("You can not generate a Dockerfile using this pack. Nothing to do.") 69 | return nil 70 | } 71 | 72 | func (p *Pack) WriteServiceYAML(templateDir string, outputDir string, shouldPrompt bool) error { 73 | 74 | dockerBase := docker_compose.DockerCompose{} 75 | dockerBase.UnmarshalFromFile(outputDir + "/docker-compose.yml") 76 | 77 | d := transform.DockerComposeTransformer{Base: dockerBase} 78 | 79 | serviceYml := d.ToServiceYml(p.Analysis.GitURL, p.Analysis.GitBranch, shouldPrompt, outputDir+"/docker-compose.yml") 80 | serviceYml.MarshalToFile(outputDir + "/service.yml") 81 | 82 | return nil 83 | } 84 | 85 | func (p *Pack) WriteDockerComposeYAML(templateDir string, outputDir string, shouldPrompt bool) error { 86 | common.PrintlnWarning("There is already an existing docker-compose.yml. Nothing to do.") 87 | return nil 88 | } 89 | 90 | func (p *Pack) WriteKubesConfig(outputDir string, shouldPrompt bool) error { 91 | common.PrintlnWarning("You can not generate a Kubernetes configuration file using this pack. Nothing to do.") 92 | return nil 93 | } 94 | 95 | func (p *Pack) GetMessages() []string { 96 | return []string{} 97 | } 98 | 99 | func (p *Pack) GetDatabases() []string { 100 | return []string{} 101 | } 102 | 103 | func (p *Pack) GetStartCommands() []string { 104 | return []string{} 105 | } 106 | 107 | func (p *Pack) StencilRepositoryPath() string { 108 | return StencilTemplatePath 109 | } 110 | 111 | func (p *Pack) PackGithubUrl() string { 112 | return dockerGithubUrl 113 | } 114 | 115 | func (p *Pack) CreateSkycapFiles(outputDir string, templateDir string, branch string) error { 116 | common.PrintlnWarning("You can not generate the Skycap configuration files using this pack. Nothing to do.") 117 | return nil 118 | } 119 | 120 | func (p *Pack) FrameworkTag() string { 121 | return "" // Not supported 122 | } 123 | func (p *Pack) LanguageTag() string { 124 | return "" // Not supported 125 | } 126 | -------------------------------------------------------------------------------- /test/node/express_mongodb_redis/src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nodebb", 3 | "license": "GPL-3.0", 4 | "description": "NodeBB Forum", 5 | "version": "1.1.2", 6 | "homepage": "http://www.nodebb.org", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/NodeBB/NodeBB/" 10 | }, 11 | "main": "app.js", 12 | "scripts": { 13 | "start": "node loader.js", 14 | "test": "./node_modules/.bin/istanbul cover ./node_modules/.bin/_mocha -- ./tests -t 10000" 15 | }, 16 | "dependencies": { 17 | "async": "~1.5.0", 18 | "autoprefixer": "^6.2.3", 19 | "bcryptjs": "~2.3.0", 20 | "body-parser": "^1.9.0", 21 | "chart.js": "^2.1.0", 22 | "colors": "^1.1.0", 23 | "compression": "^1.1.0", 24 | "connect-ensure-login": "^0.1.1", 25 | "connect-flash": "^0.1.1", 26 | "connect-mongo": "~1.1.0", 27 | "connect-multiparty": "^2.0.0", 28 | "connect-redis": "~3.1.0", 29 | "cookie-parser": "^1.3.3", 30 | "cron": "^1.0.5", 31 | "csurf": "^1.6.1", 32 | "daemon": "~1.1.0", 33 | "express": "^4.14.0", 34 | "express-session": "^1.8.2", 35 | "express-useragent": "0.2.4", 36 | "html-to-text": "2.0.0", 37 | "ip": "1.1.2", 38 | "jimp": "0.2.21", 39 | "jquery": "^3.1.0", 40 | "json-2-csv": "^2.0.22", 41 | "less": "^2.0.0", 42 | "logrotate-stream": "^0.2.3", 43 | "lru-cache": "4.0.0", 44 | "mime": "^1.3.4", 45 | "minimist": "^1.1.1", 46 | "mkdirp": "~0.5.0", 47 | "mongodb": "~2.1.3", 48 | "morgan": "^1.3.2", 49 | "mousetrap": "^1.5.3", 50 | "nconf": "~0.8.2", 51 | "nodebb-plugin-composer-default": "4.2.2", 52 | "nodebb-plugin-dbsearch": "1.0.2", 53 | "nodebb-plugin-emoji-extended": "1.1.1", 54 | "nodebb-plugin-emoji-one": "1.1.5", 55 | "nodebb-plugin-markdown": "6.0.2", 56 | "nodebb-plugin-mentions": "1.1.3", 57 | "nodebb-plugin-soundpack-default": "0.1.6", 58 | "nodebb-plugin-spam-be-gone": "0.4.10", 59 | "nodebb-rewards-essentials": "0.0.9", 60 | "nodebb-theme-lavender": "3.0.14", 61 | "nodebb-theme-persona": "4.1.37", 62 | "nodebb-theme-vanilla": "5.1.21", 63 | "nodebb-widget-essentials": "2.0.10", 64 | "nodemailer": "2.0.0", 65 | "nodemailer-sendmail-transport": "1.0.0", 66 | "nodemailer-smtp-transport": "^2.4.1", 67 | "passport": "^0.3.0", 68 | "passport-local": "1.0.0", 69 | "postcss": "^5.0.13", 70 | "prompt": "^1.0.0", 71 | "redis": "~2.6.2", 72 | "request": "^2.44.0", 73 | "rimraf": "~2.5.0", 74 | "rss": "^1.0.0", 75 | "semver": "^5.1.0", 76 | "serve-favicon": "^2.1.5", 77 | "sitemap": "^1.4.0", 78 | "socket.io": "^1.4.8", 79 | "socket.io-client": "^1.4.0", 80 | "socket.io-redis": "^1.0.0", 81 | "socketio-wildcard": "~0.3.0", 82 | "string": "^3.0.0", 83 | "templates.js": "0.3.4", 84 | "toobusy-js": "^0.5.1", 85 | "uglify-js": "^2.6.0", 86 | "underscore": "^1.8.3", 87 | "underscore.deep": "^0.5.1", 88 | "validator": "^5.0.0", 89 | "winston": "^2.1.0", 90 | "xregexp": "~3.1.0" 91 | }, 92 | "devDependencies": { 93 | "grunt": "~0.4.5", 94 | "grunt-contrib-watch": "^1.0.0", 95 | "istanbul": "^0.4.2", 96 | "mocha": "~1.13.0" 97 | }, 98 | "bugs": { 99 | "url": "https://github.com/NodeBB/NodeBB/issues" 100 | }, 101 | "engines": { 102 | "node": ">=4" 103 | }, 104 | "maintainers": [ 105 | { 106 | "name": "Andrew Rodrigues", 107 | "email": "andrew@nodebb.org", 108 | "url": "https://github.com/psychobunny" 109 | }, 110 | { 111 | "name": "Julian Lam", 112 | "email": "julian@nodebb.org", 113 | "url": "https://github.com/julianlam" 114 | }, 115 | { 116 | "name": "Barış Soner Uşaklı", 117 | "email": "baris@nodebb.org", 118 | "url": "https://github.com/barisusakli" 119 | } 120 | ] 121 | } 122 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_unicorn_redis_postgresql/src/config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 8.2 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On OS X with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On OS X with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem 'pg' 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | host: localhost 21 | # For details on connection pooling, see rails configuration guide 22 | # http://guides.rubyonrails.org/configuring.html#database-pooling 23 | pool: 5 24 | 25 | development: 26 | <<: *default 27 | database: VentBackend_development 28 | # uncomment to connect to the production database 29 | # database: VentBackend_production 30 | # host: ventbackend-test-import.cxouyocxtzkp.ap-southeast-2.rds.amazonaws.com 31 | # username: **REDACTED** 32 | # password: **REDACTED** 33 | 34 | # The specified database role being used to connect to postgres. 35 | # To create additional roles in postgres see `$ createuser --help`. 36 | # When left blank, postgres will use the default role. This is 37 | # the same name as the operating system user that initialized the database. 38 | #username: **REDACTED** 39 | 40 | # The password associated with the postgres role (username). 41 | #password: 42 | 43 | # Connect on a TCP socket. Omitted by default since the client uses a 44 | # domain socket that doesn't need configuration. Windows does not have 45 | # domain sockets, so uncomment these lines. 46 | #host: localhost 47 | 48 | # The TCP port the server listens on. Defaults to 5432. 49 | # If your server runs on a different port number, change accordingly. 50 | #port: 5432 51 | 52 | # Schema search path. The server defaults to $user,public 53 | #schema_search_path: myapp,sharedapp,public 54 | 55 | # Minimum log levels, in increasing order: 56 | # debug5, debug4, debug3, debug2, debug1, 57 | # log, notice, warning, error, fatal, and panic 58 | # Defaults to warning. 59 | #min_messages: notice 60 | 61 | # Warning: The database defined as "test" will be erased and 62 | # re-generated from your development database when you run "rake". 63 | # Do not set this db to the same as development or production. 64 | test: 65 | <<: *default 66 | database: VentBackend_test 67 | 68 | # As with config/secrets.yml, you never want to store sensitive information, 69 | # like your database password, in your source code. If your source code is 70 | # ever seen by anyone, they now have access to your database. 71 | # 72 | # Instead, provide the password as a unix environment variable when you boot 73 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 74 | # for a full rundown on how to provide these environment variables in a 75 | # production deployment. 76 | # 77 | # On Heroku and other platform providers, you may have a full connection URL 78 | # available as an environment variable. For example: 79 | # 80 | # DATABASE_URL="postgres://myuser:**REDACTED** 81 | # 82 | # You can use this database configuration with: 83 | # 84 | # production: 85 | # url: <%= ENV['DATABASE_URL'] %> 86 | # 87 | production: 88 | <<: *default 89 | database: <%= ENV['POSTGRES_DB'] %> 90 | username: <%= ENV['POSTGRES_USERNAME'] %> 91 | password: <%= ENV['POSTGRES_PASSWORD'] %> 92 | host: <%= ENV['POSTGRES_HOST'] %> 93 | pool: 48 94 | 95 | staging: 96 | <<: *default 97 | database: <%= ENV['POSTGRES_DB'] %> 98 | username: <%= ENV['POSTGRES_USERNAME'] %> 99 | password: <%= ENV['POSTGRES_PASSWORD'] %> 100 | host: <%= ENV['POSTGRES_HOST'] %> 101 | pool: 48 102 | -------------------------------------------------------------------------------- /test/ruby/rails_jobs_mysql_redis_postgrespl/src/Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 4.2.3" 4 | gem "rack-cors", require: "rack/cors" 5 | 6 | # Provides Engine for Sites 7 | gem 'sites', :git => "git@github.com:viewbook/module-gallery-slideshow.git", :ref => "f63501124972e376df6379f2325c4f8c983c5ed0" 8 | 9 | # Json serialization 10 | gem "active_model_serializers", "~> 0.9.3" 11 | 12 | # Database dependencies 13 | gem "mysql2", "~> 0.3.11" 14 | gem "pg" 15 | 16 | # Basic dependencies 17 | gem "json" 18 | gem "nokogiri" 19 | 20 | gem "sass", require: "sass" 21 | gem "sass-rails", "~> 4.0.3" 22 | 23 | # Authorization and authentication 24 | gem "devise", "~> 3.4.0" 25 | gem "devise-encryptable", "~> 0.1.0" 26 | 27 | # State machine for old and deprecated subscriptions model 28 | gem "simple_state_machine", "~> 0.6.0" 29 | # Maintain list of all domain suffixes in use 30 | gem "public_suffix", "~> 1.4.0" 31 | 32 | # HTML Sanitizer. In Rails 4.2 and above this gem will be responsible for sanitizing HTML fragments 33 | # Can be removed as explicit dependency when this app runs 4.2 34 | gem "rails-html-sanitizer" 35 | 36 | # Task scheduling 37 | gem "whenever", require: false 38 | gem "delayed_job" 39 | gem "delayed_job_active_record" 40 | 41 | # Miscellaneous libraries 42 | gem "patron" 43 | 44 | # Used by Plug::Session to keep a persistent connection to the API server. 45 | gem "net-http-persistent" 46 | 47 | # Intercom 48 | gem "intercom", "~> 2.4.4", require: false 49 | 50 | # Mailchimp api to sync user emails to mailchimp 51 | gem "mailchimp-api", require: false 52 | 53 | # Views and frontend 54 | gem "kaminari" 55 | 56 | # Storage on S3 57 | gem "aws-sdk", "~> 2.1.0", require: false 58 | 59 | # Used by sites pages to format pages 60 | gem "color" 61 | gem "radius" 62 | gem "htmlentities", "~> 4.3.3" 63 | gem "hpricot", "0.8.3" 64 | gem "simple-rss" 65 | 66 | # Used for validating EU VAT numbers 67 | gem "valvat", "~>0.6.8" 68 | 69 | # Used to detect device types and browser capabilities 70 | gem "browser", "~>0.7.0" 71 | 72 | # Naive bayes implementation used for spam detection 73 | gem "nbayes", require: false 74 | 75 | # For generating PDF files 76 | gem "prawn-rails" 77 | 78 | # React rendering 79 | gem "execjs", "~> 2.3.0" 80 | gem "therubyracer", "~> 0.12.1" 81 | gem "connection_pool", "~> 2.1.1" 82 | 83 | # Calculate image sizes 84 | gem "rmagick" 85 | 86 | group :assets do 87 | gem "sprockets", "~> 2.11" 88 | gem "jquery-rails", "~> 3.0.0" 89 | gem "uglifier", "~> 2.1.0" 90 | end 91 | 92 | group :development do 93 | gem "letter_opener" 94 | gem "thin" 95 | end 96 | 97 | group :development, :test do 98 | gem "rspec-rails", "~> 3.3.0" 99 | end 100 | 101 | group :test do 102 | gem "shoulda-matchers" 103 | 104 | gem "minitest", require: false 105 | gem "webmock", require: false 106 | 107 | gem "coveralls", require: false 108 | end 109 | 110 | group :development, :production, :staging do 111 | # ActiveAdmin adds a load time of about three seconds to the 112 | # test suite we'd rather not wait for that. 113 | gem "activeadmin", github: "gregbell/active_admin" 114 | end 115 | group :staging do 116 | # Memcache as the cache store 117 | gem 'dalli' 118 | end 119 | 120 | group :production do 121 | # Redis as the cache store 122 | gem "redis-rails" 123 | end 124 | 125 | group :staging, :production do 126 | # Track errors 127 | gem "sentry-raven", "~> 0.12.3" 128 | 129 | # New relic 130 | gem "newrelic_rpm" 131 | end 132 | -------------------------------------------------------------------------------- /packs/php/pack.go: -------------------------------------------------------------------------------- 1 | package php 2 | 3 | import ( 4 | "github.com/cloud66-oss/starter/common" 5 | "github.com/cloud66-oss/starter/packs" 6 | ) 7 | 8 | type Pack struct { 9 | packs.PackBase 10 | Analysis *Analysis 11 | } 12 | 13 | const ( 14 | StencilTemplatePath = "" //TODO: still not implemented 15 | phpGithubURL = "" //TODO: still not implemented 16 | ) 17 | 18 | func (p *Pack) Name() string { 19 | return "php" 20 | } 21 | 22 | func (p *Pack) FilesToBeAnalysed() []string { 23 | return []string{"composer.json"} 24 | } 25 | 26 | func (p *Pack) LanguageVersion() string { 27 | return "x" 28 | } 29 | 30 | func (p *Pack) Framework() string { 31 | return p.Analysis.Framework 32 | } 33 | 34 | func (p *Pack) FrameworkVersion() string { 35 | return p.Analysis.FrameworkVersion 36 | } 37 | 38 | func (p *Pack) GetSupportedLanguageVersions() []string { 39 | return nil 40 | } 41 | 42 | func (p *Pack) SetSupportedLanguageVersions(version []string) { 43 | 44 | } 45 | 46 | func (p *Pack) Detector() packs.Detector { 47 | return &Detector{PackElement: packs.PackElement{Pack: p}} 48 | } 49 | 50 | func (p *Pack) Analyze(rootDir string, environment string, shouldPrompt bool, git_repo string, git_branch string) error { 51 | var err error 52 | a := Analyzer{ 53 | AnalyzerBase: packs.AnalyzerBase{ 54 | PackElement: packs.PackElement{Pack: p}, 55 | RootDir: rootDir, 56 | ShouldPrompt: shouldPrompt, 57 | Environment: environment}} 58 | p.Analysis, err = a.Analyze() 59 | return err 60 | } 61 | 62 | func (p *Pack) WriteDockerfile(templateDir string, outputDir string, shouldPrompt bool) error { 63 | w := DockerfileWriter{ 64 | packs.DockerfileWriterBase{ 65 | PackElement: packs.PackElement{Pack: p}, 66 | TemplateWriterBase: packs.TemplateWriterBase{ 67 | TemplateDir: templateDir, 68 | OutputDir: outputDir, 69 | ShouldPrompt: shouldPrompt}}} 70 | return w.Write(p.Analysis.DockerfileContext) 71 | } 72 | 73 | func (p *Pack) WriteServiceYAML(templateDir string, outputDir string, shouldPrompt bool) error { 74 | w := ServiceYAMLWriter{ 75 | packs.ServiceYAMLWriterBase{ 76 | PackElement: packs.PackElement{Pack: p}, 77 | TemplateWriterBase: packs.TemplateWriterBase{ 78 | TemplateDir: templateDir, 79 | OutputDir: outputDir, 80 | ShouldPrompt: shouldPrompt}}} 81 | return w.Write(p.Analysis.ServiceYAMLContext) 82 | } 83 | 84 | func (p *Pack) WriteDockerComposeYAML(templateDir string, outputDir string, shouldPrompt bool) error { 85 | w := DockerComposeYAMLWriter{ 86 | packs.DockerComposeYAMLWriterBase{ 87 | PackElement: packs.PackElement{Pack: p}, 88 | TemplateWriterBase: packs.TemplateWriterBase{ 89 | TemplateDir: templateDir, 90 | OutputDir: outputDir, 91 | ShouldPrompt: shouldPrompt}}} 92 | return w.Write(p.Analysis.DockerComposeYAMLContext) 93 | } 94 | 95 | func (p *Pack) WriteKubesConfig(outputDir string, shouldPrompt bool) error { 96 | common.PrintlnWarning("You can not generate a Kubernetes configuration file using this pack. Nothing to do.") 97 | return nil 98 | } 99 | 100 | func (p *Pack) GetMessages() []string { 101 | return p.Analysis.Messages.Items 102 | } 103 | 104 | func (p *Pack) GetDatabases() []string { 105 | return []string{} 106 | } 107 | 108 | func (p *Pack) GetStartCommands() []string { 109 | return p.Analysis.ListOfStartCommands 110 | } 111 | 112 | func (p *Pack) StencilRepositoryPath() string { 113 | return StencilTemplatePath 114 | } 115 | 116 | func (p *Pack) PackGithubUrl() string { 117 | return phpGithubURL 118 | } 119 | 120 | func (p *Pack) CreateSkycapFiles(outputDir string, templateDir string, branch string) error { 121 | common.PrintlnWarning("You can not generate the Skycap configuration files using this pack. Nothing to do.") 122 | return nil 123 | } 124 | 125 | func (p *Pack) FrameworkTag() string { 126 | return "" // Not supported 127 | } 128 | func (p *Pack) LanguageTag() string { 129 | return "" // Not supported 130 | } 131 | --------------------------------------------------------------------------------