sct 0.1.2 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/Gemfile.lock +2 -2
- data/lib/sct/ClassLevelInheritableAttributes.rb +25 -0
- data/lib/sct/commands/cluster.rb +21 -16
- data/lib/sct/commands/composer.rb +29 -0
- data/lib/sct/commands/hostfile.rb +8 -26
- data/lib/sct/commands/init.rb +40 -10
- data/lib/sct/commands/mysqlproxy.rb +7 -41
- data/lib/sct/commands/php.rb +37 -0
- data/lib/sct/commands/yarn.rb +26 -0
- data/lib/sct/config.rb +44 -0
- data/lib/sct/docker/composer.rb +15 -0
- data/lib/sct/docker/docker.rb +243 -0
- data/lib/sct/docker/php.rb +14 -0
- data/lib/sct/docker/yarn.rb +16 -0
- data/lib/sct/version.rb +1 -1
- data/lib/sct.rb +1 -1
- metadata +11 -5
- data/lib/sct/constants.rb +0 -4
- data/lib/sct/sct_folder.rb +0 -35
- data/lib/sct/setup/setup.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aa3cf9bee32173cc1c48060f4ff32601c2c85458dfc82ca577f659f6c76ea167
|
4
|
+
data.tar.gz: 27e703790c149759f1c94bbcf3b332511eeb6338ff2d54ed6df992f95faab265
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3631eeb32fd0263b896715f087de24f092d1ddf1eac8b2b89f271f6f57e2e4da9cdf75ef2212eccf9ee0e4ab04ff6df09bd9c4137f99006a44f7e264f586a2c7
|
7
|
+
data.tar.gz: f3e3e98dbe9ffad2998f67ee05387840f103c3db8340317b6334ac790d1f385807453c521c70cac2cc844336f1277734862e4f42b9250e1fe0e8a7c1a10aff2e
|
data/.gitignore
CHANGED
data/Gemfile.lock
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
module ClassLevelInheritableAttributes
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
module ClassMethods
|
7
|
+
def inheritable_attributes(*args)
|
8
|
+
@inheritable_attributes ||= [:inheritable_attributes]
|
9
|
+
@inheritable_attributes += args
|
10
|
+
args.each do |arg|
|
11
|
+
class_eval %(
|
12
|
+
class << self; attr_accessor :#{arg} end
|
13
|
+
)
|
14
|
+
end
|
15
|
+
@inheritable_attributes
|
16
|
+
end
|
17
|
+
|
18
|
+
def inherited(subclass)
|
19
|
+
@inheritable_attributes.each do |inheritable_attribute|
|
20
|
+
instance_var = "@#{inheritable_attribute}"
|
21
|
+
subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/sct/commands/cluster.rb
CHANGED
@@ -3,36 +3,41 @@ require 'sct/command_interface'
|
|
3
3
|
module Sct
|
4
4
|
|
5
5
|
class ClusterCommand
|
6
|
-
|
6
|
+
|
7
7
|
IS_PUBLIC_COMMAND = true
|
8
|
-
SYNTAX = 'sct cluster'
|
8
|
+
SYNTAX = 'sct cluster up | sct cluster down'
|
9
9
|
SUMMARY = 'Starts or stops the minikube cluster'
|
10
|
-
EXAMPLE = 'sct cluster up'
|
11
|
-
EXAMPLE_DESCRIPTION = 'Starts the spend cloud cluster'
|
10
|
+
EXAMPLE = 'sct cluster up | sct cluster down'
|
11
|
+
EXAMPLE_DESCRIPTION = 'Starts or stops the spend cloud cluster'
|
12
12
|
DESCRIPTION = "Sct cluster allows you to start and stop the Spend Cloud minikube cluster"
|
13
|
-
|
14
|
-
OPTIONS = []
|
15
|
-
|
16
|
-
def initialize
|
17
13
|
|
18
|
-
|
14
|
+
OPTIONS = []
|
19
15
|
|
20
16
|
def execute(args, options)
|
17
|
+
return puts "SCT has not been initialized. Run 'sct init' first.".red unless Sct::Config.exists
|
18
|
+
|
19
|
+
if `uname -a`.match?("Microsoft")
|
20
|
+
minikube = "minikube.exe"
|
21
|
+
else
|
22
|
+
minikube = "minikube"
|
23
|
+
end
|
24
|
+
|
21
25
|
case args[0]
|
22
26
|
when "up"
|
23
|
-
system("minikube start")
|
24
|
-
system("
|
27
|
+
system("#{minikube} start")
|
28
|
+
system("sudo sct hostfile")
|
29
|
+
system("#{minikube} ssh -- 'sudo su -c \"echo 10048576 > /proc/sys/fs/inotify/max_user_watches\"'")
|
25
30
|
system("kubectl delete pod -n kube-system $(kubectl get pods -n kube-system | grep registry-creds | awk '{print $1}')")
|
26
31
|
puts "\n✔️ You can now visit your environment at 👉 https://spend-cloud.spend.cloud.local 👌"
|
27
32
|
when "down"
|
28
|
-
system("minikube stop")
|
29
|
-
else
|
33
|
+
system("#{minikube} stop")
|
34
|
+
else
|
30
35
|
puts "Unknown or missing argument. Please run 'sct cluster up' or 'sct cluster down'"
|
31
|
-
end
|
36
|
+
end
|
32
37
|
end
|
33
38
|
|
34
39
|
implements CommandInterface
|
35
|
-
|
40
|
+
|
36
41
|
end
|
37
42
|
|
38
|
-
end
|
43
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'sct/command_interface'
|
2
|
+
require 'sct/command_option'
|
3
|
+
|
4
|
+
module Sct
|
5
|
+
|
6
|
+
class ComposerCommand
|
7
|
+
|
8
|
+
IS_PUBLIC_COMMAND = true
|
9
|
+
SYNTAX = 'sct composer'
|
10
|
+
SUMMARY = 'Run composer commands through SCT'
|
11
|
+
EXAMPLE = 'sct composer install'
|
12
|
+
EXAMPLE_DESCRIPTION = 'sct composer install will update the project with the latest dependencies'
|
13
|
+
DESCRIPTION = "sct will run composer commands through the local docker installation"
|
14
|
+
|
15
|
+
OPTIONS = [
|
16
|
+
CommandOption.new("--verbose", nil, "Increase verbosity of messages."),
|
17
|
+
CommandOption.new("--require STRING", String, "Package to require with a version constraint. Should be in format foo/bar:1.0.0"),
|
18
|
+
CommandOption.new("--require-dev STRING", String, "Development requirements, see --require."),
|
19
|
+
CommandOption.new("-V", nil, "Display this application version.")
|
20
|
+
]
|
21
|
+
|
22
|
+
def execute(args, options)
|
23
|
+
require "sct/docker/composer"
|
24
|
+
Sct::Composer.exec(ARGV[1..(ARGV.length+1)])
|
25
|
+
end
|
26
|
+
|
27
|
+
implements CommandInterface
|
28
|
+
end
|
29
|
+
end
|
@@ -7,30 +7,31 @@ module Sct
|
|
7
7
|
SYNTAX = 'sct hostfile'
|
8
8
|
SUMMARY = 'adds the ingress url to the users hostfile'
|
9
9
|
DESCRIPTION = ""
|
10
|
-
EXAMPLE = "sct hostfile
|
10
|
+
EXAMPLE = "sct hostfile"
|
11
11
|
EXAMPLE_DESCRIPTION = ""
|
12
12
|
|
13
13
|
OPTIONS = []
|
14
14
|
|
15
|
-
def initialize
|
16
|
-
end
|
17
|
-
|
18
15
|
def self.options
|
19
16
|
end
|
20
17
|
|
21
18
|
def execute(args, options)
|
22
19
|
|
20
|
+
return puts "SCT has not been initialized. Run 'sct init' first.".red unless Sct::Config.exists
|
21
|
+
|
23
22
|
require 'hosts'
|
24
23
|
|
25
24
|
return unless ingressUrl
|
25
|
+
|
26
26
|
url = ingressUrl
|
27
|
+
host_path = Sct::Config.get("host-path")
|
27
28
|
|
28
29
|
if !options.path.nil?
|
29
30
|
hosts = Hosts::File.read(options.path)
|
30
|
-
elsif
|
31
|
-
hosts = Hosts::File.read(
|
31
|
+
elsif host_path
|
32
|
+
hosts = Hosts::File.read(host_path)
|
32
33
|
else
|
33
|
-
puts "No hostpath found in
|
34
|
+
puts "No hostpath found in config file. Using default /etc/hosts".yellow
|
34
35
|
hosts = Hosts::File.read('/etc/hosts')
|
35
36
|
end
|
36
37
|
|
@@ -103,25 +104,6 @@ module Sct
|
|
103
104
|
return Sct::Helpers.ingressUrl
|
104
105
|
end
|
105
106
|
|
106
|
-
def setup
|
107
|
-
|
108
|
-
return false unless Sct::SctFolder.setup?
|
109
|
-
|
110
|
-
return true
|
111
|
-
|
112
|
-
end
|
113
|
-
|
114
|
-
def sct_file
|
115
|
-
|
116
|
-
return unless setup
|
117
|
-
|
118
|
-
sct_file_string = File.read(Sct::SctFolder.sctfile_path)
|
119
|
-
|
120
|
-
sct_file_hash = Sct::Helpers.to_hash(sct_file_string)
|
121
|
-
|
122
|
-
return sct_file_hash
|
123
|
-
end
|
124
|
-
|
125
107
|
implements CommandInterface
|
126
108
|
|
127
109
|
end
|
data/lib/sct/commands/init.rb
CHANGED
@@ -1,29 +1,59 @@
|
|
1
1
|
require 'sct/command_interface'
|
2
|
+
require 'highline'
|
2
3
|
|
3
4
|
module Sct
|
4
5
|
|
5
6
|
class InitCommand
|
6
|
-
|
7
|
+
|
7
8
|
IS_PUBLIC_COMMAND = true
|
8
9
|
SYNTAX = 'sct init'
|
9
10
|
SUMMARY = 'Initialize a base configuration file for sct'
|
10
11
|
EXAMPLE = 'sct init'
|
11
|
-
EXAMPLE_DESCRIPTION = 'sct init will create a
|
12
|
-
DESCRIPTION = "sct init will create a configuration file
|
13
|
-
|
12
|
+
EXAMPLE_DESCRIPTION = 'sct init will create a configuration file'
|
13
|
+
DESCRIPTION = "sct init will create a configuration file"
|
14
|
+
|
14
15
|
OPTIONS = []
|
15
|
-
|
16
|
-
def initialize
|
17
16
|
|
17
|
+
def initialize
|
18
18
|
end
|
19
19
|
|
20
20
|
def execute(args, options)
|
21
|
-
|
22
|
-
Sct::
|
21
|
+
|
22
|
+
Sct::Config.dir
|
23
|
+
|
24
|
+
cli = HighLine.new
|
25
|
+
|
26
|
+
email = cli.ask("What is your email address?") { |q|
|
27
|
+
q.validate = URI::MailTo::EMAIL_REGEXP
|
28
|
+
}
|
29
|
+
|
30
|
+
cloud_proxy_path = cli.ask("What is the path of your cloud proxy json credentials?") { |q|
|
31
|
+
q.default = "~/.config/gcloud/application_default_credentials.json"
|
32
|
+
}
|
33
|
+
|
34
|
+
host_path = cli.choose do |menu|
|
35
|
+
menu.prompt = "What is the path of your hostfile?"
|
36
|
+
menu.choice(:unix) { "/etc/hosts" }
|
37
|
+
menu.choices(:windows) { "/mnt/c/Windows/System32/drivers/etc/hosts" }
|
38
|
+
menu.default = :unix
|
39
|
+
end
|
40
|
+
|
41
|
+
contents = ""
|
42
|
+
contents << "email=#{email}\n"
|
43
|
+
contents << "cloud-proxy-path=#{File.expand_path(cloud_proxy_path)}\n"
|
44
|
+
contents << "host-path=#{File.expand_path(host_path)}\n"
|
45
|
+
|
46
|
+
if !File.directory?(Sct::Config.dir)
|
47
|
+
FileUtils.mkdir_p(Sct::Config.dir)
|
48
|
+
end
|
49
|
+
|
50
|
+
File.write(Sct::Config.path, contents)
|
51
|
+
|
52
|
+
puts "Generated config file at #{Sct::Config.path}"
|
23
53
|
end
|
24
54
|
|
25
55
|
implements CommandInterface
|
26
|
-
|
56
|
+
|
27
57
|
end
|
28
58
|
|
29
|
-
end
|
59
|
+
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
require 'sct/command_interface'
|
2
2
|
require 'sct/command_option'
|
3
|
-
require "sct/
|
3
|
+
require "sct/config"
|
4
4
|
require "sct/setup/helpers"
|
5
5
|
|
6
6
|
module Sct
|
7
7
|
|
8
8
|
class Mysql_proxyCommand
|
9
9
|
|
10
|
-
|
11
10
|
DEFAULT_SECRET_NAME = "gcloud-credentials"
|
12
11
|
|
13
12
|
IS_PUBLIC_COMMAND = true
|
@@ -16,55 +15,22 @@ module Sct
|
|
16
15
|
DESCRIPTION = ""
|
17
16
|
EXAMPLE = ""
|
18
17
|
EXAMPLE_DESCRIPTION = ""
|
19
|
-
|
20
|
-
OPTIONS = []
|
21
|
-
|
22
|
-
@path
|
23
|
-
@secret_name
|
24
|
-
|
25
|
-
def initialize
|
26
|
-
|
27
|
-
return unless setup
|
28
|
-
|
29
|
-
@path = sct_file["cloud-proxy-path"]
|
30
|
-
@secret_name = DEFAULT_SECRET_NAME
|
31
|
-
end
|
32
|
-
|
33
|
-
def self.options
|
34
|
-
|
35
|
-
end
|
18
|
+
OPTIONS = []
|
36
19
|
|
37
20
|
def execute(args, options)
|
38
21
|
|
39
|
-
return puts "
|
22
|
+
return puts "SCT has not been initialized. Run 'sct init' first.".red unless Sct::Config.exists
|
40
23
|
|
24
|
+
path = Sct::Config.get('cloud-proxy-path')
|
25
|
+
|
41
26
|
system("kubectl delete secret gcloud-credentials")
|
42
|
-
system("kubectl create secret generic gcloud-credentials --from-file=#{
|
27
|
+
system("kubectl create secret generic gcloud-credentials --from-file=#{path}")
|
43
28
|
|
44
|
-
puts "Authenticated with secret-name: '#{
|
29
|
+
puts "Authenticated with secret-name: '#{DEFAULT_SECRET_NAME}'".green
|
45
30
|
|
46
31
|
return true
|
47
32
|
end
|
48
33
|
|
49
|
-
def setup
|
50
|
-
|
51
|
-
return false unless Sct::SctFolder.setup?
|
52
|
-
|
53
|
-
return true
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def sct_file
|
58
|
-
|
59
|
-
return unless setup
|
60
|
-
|
61
|
-
sct_file_string = File.read(Sct::SctFolder.sctfile_path)
|
62
|
-
|
63
|
-
sct_file_hash = Sct::Helpers.to_hash(sct_file_string)
|
64
|
-
|
65
|
-
return sct_file_hash
|
66
|
-
end
|
67
|
-
|
68
34
|
implements CommandInterface
|
69
35
|
|
70
36
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'sct/command_interface'
|
2
|
+
require 'sct/command_option'
|
3
|
+
|
4
|
+
module Sct
|
5
|
+
|
6
|
+
class PhpCommand
|
7
|
+
|
8
|
+
IS_PUBLIC_COMMAND = true
|
9
|
+
SYNTAX = 'sct php'
|
10
|
+
SUMMARY = 'Run php commands through SCT'
|
11
|
+
EXAMPLE = 'sct php -r "echo \'Hello World!\';"'
|
12
|
+
EXAMPLE_DESCRIPTION = 'sct php -r will execute a command directly through the php interpreter'
|
13
|
+
DESCRIPTION = "sct will run php commands through the local docker installation"
|
14
|
+
|
15
|
+
OPTIONS = [
|
16
|
+
CommandOption.new("-r", String, "Run php code directy through the interpreter"),
|
17
|
+
CommandOption.new("-V", nil, "Get the current php version. Note that it's a capital V. The lowercase v will return the SCT tool version"),
|
18
|
+
]
|
19
|
+
|
20
|
+
def execute(args, options)
|
21
|
+
require "sct/docker/php"
|
22
|
+
|
23
|
+
# Workaround for the version option being caught by the SCT tool itself
|
24
|
+
args=ARGV[1..(ARGV.length+1)].map { |arg| arg == '-V' ? arg = '-v' : arg}
|
25
|
+
|
26
|
+
# Another workaround for the -r option to add quotes around the value
|
27
|
+
if args.include? '-r'
|
28
|
+
codeIndex = args.index('-r') + 1
|
29
|
+
args[codeIndex] = "\"#{args[codeIndex]}\""
|
30
|
+
end
|
31
|
+
|
32
|
+
Sct::Php.exec(args)
|
33
|
+
end
|
34
|
+
|
35
|
+
implements CommandInterface
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'sct/command_interface'
|
2
|
+
require 'sct/command_option'
|
3
|
+
|
4
|
+
module Sct
|
5
|
+
|
6
|
+
class YarnCommand
|
7
|
+
|
8
|
+
IS_PUBLIC_COMMAND = true
|
9
|
+
SYNTAX = 'sct yarn'
|
10
|
+
SUMMARY = 'Run yarn commands through SCT'
|
11
|
+
EXAMPLE = 'sct yarn dev'
|
12
|
+
EXAMPLE_DESCRIPTION = 'sct yarn dev will start the dev installation of the current project'
|
13
|
+
DESCRIPTION = "sct will run yarn commands through the local docker installation"
|
14
|
+
|
15
|
+
OPTIONS = [
|
16
|
+
CommandOption.new("--port PORTNUMBER", Integer, "The portnumber on which the server will be deployed")
|
17
|
+
]
|
18
|
+
|
19
|
+
def execute(args, options)
|
20
|
+
require "sct/docker/yarn"
|
21
|
+
Sct::Yarn.exec(ARGV[1..(ARGV.length+1)])
|
22
|
+
end
|
23
|
+
|
24
|
+
implements CommandInterface
|
25
|
+
end
|
26
|
+
end
|
data/lib/sct/config.rb
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Sct
|
2
|
+
class Config
|
3
|
+
|
4
|
+
def self.dir
|
5
|
+
user = ENV["SUDO_USER"] || ENV["USER"]
|
6
|
+
|
7
|
+
if `uname -a`.match?("Darwin")
|
8
|
+
home = "/Users"
|
9
|
+
else
|
10
|
+
home = "/home"
|
11
|
+
end
|
12
|
+
|
13
|
+
return "#{home}/#{user}/.config/sct"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.path
|
17
|
+
return File.expand_path(File.join(self.dir, 'config'))
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.exists
|
21
|
+
return File.exists?(Config.path)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.get(key)
|
25
|
+
config = self.read
|
26
|
+
|
27
|
+
if !config.key?(key)
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
|
31
|
+
return config[key]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.read
|
35
|
+
if !self.exists
|
36
|
+
return {}
|
37
|
+
end
|
38
|
+
|
39
|
+
contents = File.read(self.path)
|
40
|
+
|
41
|
+
return Sct::Helpers.to_hash(contents)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "sct/docker/docker"
|
2
|
+
|
3
|
+
module Sct
|
4
|
+
class Composer < Docker
|
5
|
+
|
6
|
+
# Configure the Yarn command
|
7
|
+
def self.config
|
8
|
+
self.setImage("eu.gcr.io/dev-pasc-vcdm/helpers-composer:latest", true)
|
9
|
+
self.setPwdAsVolume("/app")
|
10
|
+
self.addVolume(self.convertPath(self.getTrueHomePath()+"/.composer") , "/.composer")
|
11
|
+
self.setCurrentUserAndGroup()
|
12
|
+
self.setEntrypoint("composer")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require "sct/ClassLevelInheritableAttributes"
|
2
|
+
|
3
|
+
module Sct
|
4
|
+
class Docker
|
5
|
+
include ClassLevelInheritableAttributes
|
6
|
+
inheritable_attributes :image, :is_private_registry, :entrypoint, :volumes, :ports, :extra_arguments
|
7
|
+
|
8
|
+
@image = nil
|
9
|
+
@is_private_registry = false
|
10
|
+
@entrypoint = nil
|
11
|
+
|
12
|
+
@volumes = {}
|
13
|
+
@ports = {}
|
14
|
+
@user_group = []
|
15
|
+
@extra_arguments = {}
|
16
|
+
|
17
|
+
###
|
18
|
+
# The Docker command configuration. This has to be able to execute the command properly
|
19
|
+
###
|
20
|
+
def self.config
|
21
|
+
# Run some initialization commands
|
22
|
+
end
|
23
|
+
|
24
|
+
###
|
25
|
+
# Execute the configured command
|
26
|
+
###
|
27
|
+
def self.exec(cli_arguments)
|
28
|
+
|
29
|
+
cli_arguments.each do | argument |
|
30
|
+
self.addExtraArgument(argument)
|
31
|
+
end
|
32
|
+
|
33
|
+
self.config()
|
34
|
+
|
35
|
+
# Check if the basic variables are set
|
36
|
+
if !@image || @image.empty?
|
37
|
+
raise LoadError, "The required image is not defined for this command"
|
38
|
+
end
|
39
|
+
|
40
|
+
if !self.checkForImage() && @is_private_registry
|
41
|
+
if !self.loginToPrivateRegistry()
|
42
|
+
raise RuntimeError, "Could not authenticate to GCR (" + $?.exitstatus + ")"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
self.runCommand()
|
47
|
+
end
|
48
|
+
|
49
|
+
###
|
50
|
+
# The image for this Docker command
|
51
|
+
###
|
52
|
+
def self.setImage(image, is_private_registry=false)
|
53
|
+
@image = image
|
54
|
+
@is_private_registry = is_private_registry
|
55
|
+
end
|
56
|
+
|
57
|
+
###
|
58
|
+
# Set the current PWD as a volume on the specified path in the container
|
59
|
+
###
|
60
|
+
def self.setPwdAsVolume(volume_path)
|
61
|
+
pwd = `pwd -P`
|
62
|
+
|
63
|
+
if self.operatingSystem() == "Windows"
|
64
|
+
pwd=self.convertPath(pwd)
|
65
|
+
end
|
66
|
+
|
67
|
+
addVolume(pwd, volume_path)
|
68
|
+
end
|
69
|
+
|
70
|
+
###
|
71
|
+
# Add an extra volume in the container
|
72
|
+
###
|
73
|
+
def self.addVolume(localPath, volume_path)
|
74
|
+
@volumes[localPath] = volume_path
|
75
|
+
end
|
76
|
+
|
77
|
+
###
|
78
|
+
# Add a port mapping for the container
|
79
|
+
###
|
80
|
+
def self.mapPort(external_port, container_port = nil)
|
81
|
+
|
82
|
+
external_port=String(external_port)
|
83
|
+
container_port=String(container_port)
|
84
|
+
|
85
|
+
if container_port.empty?
|
86
|
+
container_port = external_port
|
87
|
+
end
|
88
|
+
|
89
|
+
@ports[external_port] = container_port
|
90
|
+
end
|
91
|
+
|
92
|
+
###
|
93
|
+
# Set the current user and group in the container
|
94
|
+
###
|
95
|
+
def self.setCurrentUserAndGroup
|
96
|
+
@user_group = []
|
97
|
+
@user_group << `id -u`
|
98
|
+
@user_group << `id -g`
|
99
|
+
end
|
100
|
+
|
101
|
+
###
|
102
|
+
# Set the entrypoint for the command in the container
|
103
|
+
###
|
104
|
+
def self.setEntrypoint(entrypoint)
|
105
|
+
@entrypoint=entrypoint
|
106
|
+
end
|
107
|
+
|
108
|
+
###
|
109
|
+
# Add extra arguments to be configured for the container
|
110
|
+
###
|
111
|
+
def self.addExtraArgument(argument, value=nil)
|
112
|
+
argument = String(argument)
|
113
|
+
|
114
|
+
if value
|
115
|
+
value = String(value)
|
116
|
+
end
|
117
|
+
|
118
|
+
self.extra_arguments[argument] = value
|
119
|
+
end
|
120
|
+
|
121
|
+
###
|
122
|
+
# Check if the image is already present in the system
|
123
|
+
###
|
124
|
+
def self.checkForImage
|
125
|
+
image_list=`docker images -q #{@image} 2> /dev/null`
|
126
|
+
|
127
|
+
return image_list && !image_list.empty?
|
128
|
+
end
|
129
|
+
|
130
|
+
###
|
131
|
+
# Login to the private container registry with the cloud credentials
|
132
|
+
###
|
133
|
+
def self.loginToPrivateRegistry
|
134
|
+
`docker login -u oauth2accesstoken -p "$(gcloud auth application-default print-access-token)" https://eu.gcr.io &>2`
|
135
|
+
return $?.success?
|
136
|
+
end
|
137
|
+
|
138
|
+
###
|
139
|
+
# Run the command
|
140
|
+
###
|
141
|
+
def self.runCommand()
|
142
|
+
command = self.compileCommand()
|
143
|
+
|
144
|
+
system(command)
|
145
|
+
|
146
|
+
return $?.success?
|
147
|
+
end
|
148
|
+
|
149
|
+
###
|
150
|
+
# Compile the command with all options
|
151
|
+
###
|
152
|
+
def self.compileCommand()
|
153
|
+
# Basic docker run command
|
154
|
+
command = self.addToCommandString("" , "docker run --rm -it")
|
155
|
+
|
156
|
+
# Attach configured volumes
|
157
|
+
if @volumes
|
158
|
+
@volumes.each do |local_path, container_path|
|
159
|
+
command = self.addToCommandString(command, "--volume " + local_path +":"+ container_path)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
# Map configured ports
|
164
|
+
if @ports
|
165
|
+
@ports.each do |external_port, container_port|
|
166
|
+
command = self.addToCommandString(command, "-p " + external_port +":"+ container_port)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
if @user_group
|
171
|
+
command = self.addToCommandString(command, "--user "+ String(@user_group.shift()) +":"+ String(@user_group.shift()))
|
172
|
+
end
|
173
|
+
|
174
|
+
# Add image to command
|
175
|
+
command = self.addToCommandString(command, @image)
|
176
|
+
|
177
|
+
if @entrypoint
|
178
|
+
command = self.addToCommandString(command, String(@entrypoint))
|
179
|
+
end
|
180
|
+
|
181
|
+
# Append arguments and options to command
|
182
|
+
if @extra_arguments
|
183
|
+
@extra_arguments.each do |argument, value|
|
184
|
+
if value && !value.empty?
|
185
|
+
command = self.addToCommandString(command, argument+"="+value)
|
186
|
+
else
|
187
|
+
command = self.addToCommandString(command, argument)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
return command
|
193
|
+
end
|
194
|
+
|
195
|
+
###
|
196
|
+
# Append a part to the command string and remove any unwanted characters
|
197
|
+
###
|
198
|
+
def self.addToCommandString(command_string, append)
|
199
|
+
return command_string + append.gsub(/\r?\n/, "") + " "
|
200
|
+
end
|
201
|
+
|
202
|
+
###
|
203
|
+
# Check the operating system on which this command is being run
|
204
|
+
###
|
205
|
+
def self.operatingSystem()
|
206
|
+
proc = `uname -a`
|
207
|
+
|
208
|
+
case proc
|
209
|
+
when /Microsoft/
|
210
|
+
os = "Windows"
|
211
|
+
when /Darwin/
|
212
|
+
os = "MacOS"
|
213
|
+
else
|
214
|
+
os = "Ubuntu"
|
215
|
+
end
|
216
|
+
|
217
|
+
return os
|
218
|
+
end
|
219
|
+
|
220
|
+
###
|
221
|
+
# Get the actual home path of the user. This may be different depending on the operating system
|
222
|
+
###
|
223
|
+
def self.getTrueHomePath
|
224
|
+
home_path = `echo ~`
|
225
|
+
if self.operatingSystem() == "Windows"
|
226
|
+
home_path = self.convertPath(`cmd.exe /c echo %userprofile%`, false)
|
227
|
+
end
|
228
|
+
|
229
|
+
return home_path
|
230
|
+
end
|
231
|
+
|
232
|
+
###
|
233
|
+
# Convert the unix paths to Windows paths for Windows systems
|
234
|
+
###
|
235
|
+
def self.convertPath(path, to_native=true)
|
236
|
+
if self.operatingSystem() == "Windows" && to_native
|
237
|
+
return path.gsub(/\/mnt\/c/, 'C:/').gsub(/\/\//, '/').gsub(/\\\\/, "/").gsub(/\r\n?/, '')
|
238
|
+
else
|
239
|
+
return path.gsub(/C:\\/, '/mnt/c').gsub(/\\\\/, "/").gsub(/\\/, '/').gsub(/\r\n?/, '')
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require "sct/docker/docker"
|
2
|
+
|
3
|
+
module Sct
|
4
|
+
class Php < Docker
|
5
|
+
|
6
|
+
# Configure the Yarn command
|
7
|
+
def self.config
|
8
|
+
self.setImage("eu.gcr.io/dev-pasc-vcdm/proactive-base:latest", true)
|
9
|
+
self.setPwdAsVolume("/var/www")
|
10
|
+
self.setCurrentUserAndGroup()
|
11
|
+
self.setEntrypoint("php")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require "sct/docker/docker"
|
2
|
+
|
3
|
+
module Sct
|
4
|
+
class Yarn < Docker
|
5
|
+
|
6
|
+
# Configure the Yarn command
|
7
|
+
def self.config
|
8
|
+
self.setImage("eu.gcr.io/dev-pasc-vcdm/helpers-yarn:latest", true)
|
9
|
+
self.setPwdAsVolume("/app")
|
10
|
+
self.addVolume(self.convertPath(self.getTrueHomePath()+"/.cache") , "/.cache")
|
11
|
+
self.mapPort(8081, 8080)
|
12
|
+
self.mapPort(9001)
|
13
|
+
self.setCurrentUserAndGroup()
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/sct/version.rb
CHANGED
data/lib/sct.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Reshad Farid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-01-
|
11
|
+
date: 2020-01-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: class_interface
|
@@ -147,17 +147,23 @@ files:
|
|
147
147
|
- lib/.DS_Store
|
148
148
|
- lib/sct.rb
|
149
149
|
- lib/sct/.DS_Store
|
150
|
+
- lib/sct/ClassLevelInheritableAttributes.rb
|
150
151
|
- lib/sct/command.rb
|
151
152
|
- lib/sct/command_interface.rb
|
152
153
|
- lib/sct/command_option.rb
|
153
154
|
- lib/sct/commands/cluster.rb
|
155
|
+
- lib/sct/commands/composer.rb
|
154
156
|
- lib/sct/commands/hostfile.rb
|
155
157
|
- lib/sct/commands/init.rb
|
156
158
|
- lib/sct/commands/mysqlproxy.rb
|
157
|
-
- lib/sct/
|
158
|
-
- lib/sct/
|
159
|
+
- lib/sct/commands/php.rb
|
160
|
+
- lib/sct/commands/yarn.rb
|
161
|
+
- lib/sct/config.rb
|
162
|
+
- lib/sct/docker/composer.rb
|
163
|
+
- lib/sct/docker/docker.rb
|
164
|
+
- lib/sct/docker/php.rb
|
165
|
+
- lib/sct/docker/yarn.rb
|
159
166
|
- lib/sct/setup/helpers.rb
|
160
|
-
- lib/sct/setup/setup.rb
|
161
167
|
- lib/sct/version.rb
|
162
168
|
- sct.gemspec
|
163
169
|
homepage: https://gitlab.com/proactive-software/packages/sct
|
data/lib/sct/constants.rb
DELETED
data/lib/sct/sct_folder.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
module Sct
|
2
|
-
class SctFolder
|
3
|
-
FOLDER_NAME = "sct"
|
4
|
-
|
5
|
-
def self.path
|
6
|
-
value ||= "./#{FOLDER_NAME}/" if File.directory?("./#{FOLDER_NAME}/")
|
7
|
-
value ||= "./.#{FOLDER_NAME}/" if File.directory?("./.#{FOLDER_NAME}/") # hidden folder
|
8
|
-
value ||= "./" if File.basename(Dir.getwd) == FOLDER_NAME && File.exist?('Sctfile') # inside the folder
|
9
|
-
value ||= "./" if File.basename(Dir.getwd) == ".#{FOLDER_NAME}" && File.exist?('Sctfile') # inside the folder and hidden
|
10
|
-
return value
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.sctfile_path
|
14
|
-
return nil if self.path.nil?
|
15
|
-
|
16
|
-
path = File.join(self.path, 'Sctfile')
|
17
|
-
return path if File.exist?(path)
|
18
|
-
return nil
|
19
|
-
end
|
20
|
-
|
21
|
-
# Does a sct configuration already exist?
|
22
|
-
def self.setup?
|
23
|
-
return false unless self.sctfile_path
|
24
|
-
File.exist?(self.sctfile_path)
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.create_folder!(path = nil)
|
28
|
-
path = File.join(path || '.', FOLDER_NAME)
|
29
|
-
return if File.directory?(path) # directory is already there
|
30
|
-
puts "Found a folder called 'sct' at path '#{path}', please delete it" if File.exist?(path)
|
31
|
-
FileUtils.mkdir_p(path)
|
32
|
-
puts "Created new folder '#{path}'."
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
data/lib/sct/setup/setup.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require 'highline'
|
2
|
-
|
3
|
-
module Sct
|
4
|
-
class Setup
|
5
|
-
|
6
|
-
attr_accessor :sctfile_content
|
7
|
-
|
8
|
-
def self.start
|
9
|
-
|
10
|
-
require "sct/sct_folder"
|
11
|
-
|
12
|
-
if Sct::SctFolder.setup?
|
13
|
-
puts "Already setup at path `#{Sct::SctFolder.path}`"
|
14
|
-
return
|
15
|
-
end
|
16
|
-
|
17
|
-
Sct::SctFolder.create_folder!
|
18
|
-
|
19
|
-
setup = self.new
|
20
|
-
setup.write_sctfile
|
21
|
-
|
22
|
-
end
|
23
|
-
|
24
|
-
def write_sctfile
|
25
|
-
|
26
|
-
sctfile_file_name = "Sctfile"
|
27
|
-
|
28
|
-
cli = HighLine.new
|
29
|
-
|
30
|
-
email = cli.ask("What is your email address?") { |q|
|
31
|
-
q.validate = URI::MailTo::EMAIL_REGEXP
|
32
|
-
}
|
33
|
-
|
34
|
-
cloud_proxy = cli.ask("What is the path of your cloud proxy json credentials?") { |q|
|
35
|
-
q.default = "/.config/gcloud/application_default_credentials.json"
|
36
|
-
}
|
37
|
-
|
38
|
-
host_path = cli.choose do |menu|
|
39
|
-
menu.prompt = "What is the path of your hostfile?"
|
40
|
-
menu.choice(:unix) { "/etc/hosts" }
|
41
|
-
menu.choices(:windows) { "/mnt/c/Windows/System32/drivers/etc/hosts" }
|
42
|
-
menu.default = :unix
|
43
|
-
end
|
44
|
-
|
45
|
-
self.sctfile_content = ""
|
46
|
-
self.sctfile_content << "#{email} \n"
|
47
|
-
self.sctfile_content << "cloud-proxy-path=#{cloud_proxy} \n"
|
48
|
-
self.sctfile_content << "hostpath=#{host_path} \n"
|
49
|
-
|
50
|
-
sctfile_path = File.join(Sct::SctFolder.path, sctfile_file_name)
|
51
|
-
|
52
|
-
File.write(sctfile_path, self.sctfile_content)
|
53
|
-
|
54
|
-
puts "Generated Sctfile at #{sctfile_path}"
|
55
|
-
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|