stork 0.1.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +10 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +75 -0
- data/LICENSE +201 -0
- data/README.md +61 -0
- data/Rakefile +25 -0
- data/bin/stork +97 -0
- data/bin/storkctl +62 -0
- data/lib/stork/builder.rb +104 -0
- data/lib/stork/client/plugins/host_install.rb +19 -0
- data/lib/stork/client/plugins/host_list.rb +12 -0
- data/lib/stork/client/plugins/host_localboot.rb +19 -0
- data/lib/stork/client/plugins/host_show.rb +19 -0
- data/lib/stork/collection/base.rb +45 -0
- data/lib/stork/collection/chefs.rb +6 -0
- data/lib/stork/collection/distros.rb +6 -0
- data/lib/stork/collection/hosts.rb +6 -0
- data/lib/stork/collection/layouts.rb +6 -0
- data/lib/stork/collection/networks.rb +6 -0
- data/lib/stork/collection/snippets.rb +6 -0
- data/lib/stork/collection/templates.rb +6 -0
- data/lib/stork/collections.rb +38 -0
- data/lib/stork/configuration.rb +98 -0
- data/lib/stork/deploy/command.rb +59 -0
- data/lib/stork/deploy/install_script.rb +39 -0
- data/lib/stork/deploy/kickstart_binding.rb +222 -0
- data/lib/stork/deploy/section.rb +30 -0
- data/lib/stork/deploy/snippet_binding.rb +49 -0
- data/lib/stork/plugin.rb +54 -0
- data/lib/stork/pxe.rb +70 -0
- data/lib/stork/resource/base.rb +42 -0
- data/lib/stork/resource/chef.rb +81 -0
- data/lib/stork/resource/delegator.rb +50 -0
- data/lib/stork/resource/distro.rb +30 -0
- data/lib/stork/resource/firewall.rb +47 -0
- data/lib/stork/resource/host.rb +202 -0
- data/lib/stork/resource/interface.rb +125 -0
- data/lib/stork/resource/layout.rb +50 -0
- data/lib/stork/resource/logical_volume.rb +49 -0
- data/lib/stork/resource/network.rb +36 -0
- data/lib/stork/resource/partition.rb +47 -0
- data/lib/stork/resource/password.rb +26 -0
- data/lib/stork/resource/repo.rb +29 -0
- data/lib/stork/resource/snippet.rb +20 -0
- data/lib/stork/resource/template.rb +24 -0
- data/lib/stork/resource/timezone.rb +31 -0
- data/lib/stork/resource/volume_group.rb +31 -0
- data/lib/stork/resources.rb +17 -0
- data/lib/stork/server/application.rb +127 -0
- data/lib/stork/server/control.rb +38 -0
- data/lib/stork/version.rb +4 -0
- data/lib/stork.rb +30 -0
- data/specs/builder_spec.rb +14 -0
- data/specs/collections_spec.rb +72 -0
- data/specs/configuration_spec.rb +151 -0
- data/specs/keys/snakeoil-root.pem +27 -0
- data/specs/keys/snakeoil-validation.pem +27 -0
- data/specs/kickstart_spec.rb +36 -0
- data/specs/pxe_spec.rb +57 -0
- data/specs/resource_chef_spec.rb +122 -0
- data/specs/resource_distro_spec.rb +38 -0
- data/specs/resource_firewall_spec.rb +71 -0
- data/specs/resource_host_spec.rb +323 -0
- data/specs/resource_interface_spec.rb +158 -0
- data/specs/resource_layout_spec.rb +78 -0
- data/specs/resource_logical_volume_spec.rb +44 -0
- data/specs/resource_network_spec.rb +45 -0
- data/specs/resource_partition_spec.rb +51 -0
- data/specs/resource_password_spec.rb +10 -0
- data/specs/resource_repo_spec.rb +43 -0
- data/specs/resource_snippet_spec.rb +10 -0
- data/specs/resource_template_spec.rb +5 -0
- data/specs/resource_timezone_spec.rb +5 -0
- data/specs/resource_volume_group_spec.rb +23 -0
- data/specs/scripts/kssetup.sh +24 -0
- data/specs/scripts/ksvalidate.sh +21 -0
- data/specs/server_spec.rb +84 -0
- data/specs/spec_helper.rb +33 -0
- data/specs/stork/authorized_keys +1 -0
- data/specs/stork/bundles/chefs/default.rb +9 -0
- data/specs/stork/bundles/distros/centos.rb +5 -0
- data/specs/stork/bundles/hosts/example.org.rb +66 -0
- data/specs/stork/bundles/layouts/home.rb +33 -0
- data/specs/stork/bundles/networks/local.rb +6 -0
- data/specs/stork/bundles/networks/org.rb +7 -0
- data/specs/stork/bundles/snippets/authorized-keys.erb +10 -0
- data/specs/stork/bundles/snippets/chef-bootstrap.erb +104 -0
- data/specs/stork/bundles/snippets/chef-reconfigure.erb +22 -0
- data/specs/stork/bundles/snippets/etc-hosts.erb +6 -0
- data/specs/stork/bundles/snippets/network-config.erb +7 -0
- data/specs/stork/bundles/snippets/noop.erb +1 -0
- data/specs/stork/bundles/snippets/notify.erb +2 -0
- data/specs/stork/bundles/snippets/ntp.erb +2 -0
- data/specs/stork/bundles/snippets/resolv-conf.erb +6 -0
- data/specs/stork/bundles/snippets/setup.erb +1 -0
- data/specs/stork/bundles/templates/default.ks.erb +25 -0
- data/specs/stork/config.rb +11 -0
- data/stork.gemspec +35 -0
- metadata +329 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Interface < Base
|
4
|
+
attr_accessor :ethtool
|
5
|
+
attr_accessor :ip
|
6
|
+
attr_accessor :mtu
|
7
|
+
attr_accessor :bootproto
|
8
|
+
attr_accessor :onboot
|
9
|
+
attr_accessor :ipv4
|
10
|
+
attr_accessor :ipv6
|
11
|
+
attr_accessor :dns
|
12
|
+
attr_accessor :defroute
|
13
|
+
attr_accessor :network
|
14
|
+
|
15
|
+
def setup
|
16
|
+
@network = Network.new
|
17
|
+
@bootproto = :dhcp
|
18
|
+
@ip = nil
|
19
|
+
@mtu = nil
|
20
|
+
@onboot = true
|
21
|
+
@ipv4 = true
|
22
|
+
@ipv6 = false
|
23
|
+
@defroute = true
|
24
|
+
@ethtool = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def validate!
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
def netmask
|
32
|
+
network.netmask
|
33
|
+
end
|
34
|
+
|
35
|
+
def gateway
|
36
|
+
network.gateway
|
37
|
+
end
|
38
|
+
|
39
|
+
def nameservers
|
40
|
+
network.nameservers
|
41
|
+
end
|
42
|
+
|
43
|
+
def search_paths
|
44
|
+
network.search_paths
|
45
|
+
end
|
46
|
+
|
47
|
+
def noipv4
|
48
|
+
!ipv4
|
49
|
+
end
|
50
|
+
|
51
|
+
def noipv6
|
52
|
+
!ipv6
|
53
|
+
end
|
54
|
+
|
55
|
+
def nodns
|
56
|
+
!dns
|
57
|
+
end
|
58
|
+
|
59
|
+
def nodefroute
|
60
|
+
!defroute
|
61
|
+
end
|
62
|
+
|
63
|
+
def static?
|
64
|
+
@bootproto == :static
|
65
|
+
end
|
66
|
+
|
67
|
+
def hashify
|
68
|
+
{
|
69
|
+
'ip' => ip,
|
70
|
+
'bootproto' => bootproto,
|
71
|
+
'netmask' => netmask,
|
72
|
+
'gateway' => gateway,
|
73
|
+
'nameservers' => nameservers,
|
74
|
+
'search_paths' => search_paths
|
75
|
+
}
|
76
|
+
end
|
77
|
+
|
78
|
+
alias_method :device, :name
|
79
|
+
|
80
|
+
class InterfaceDelegator < Stork::Resource::Delegator
|
81
|
+
flag :onboot
|
82
|
+
flag :ipv4
|
83
|
+
flag :ipv6
|
84
|
+
flag :dns
|
85
|
+
flag :defroute
|
86
|
+
|
87
|
+
def ethtool(ethtool)
|
88
|
+
delegated.ethtool = ethtool
|
89
|
+
end
|
90
|
+
|
91
|
+
def ip(ip)
|
92
|
+
delegated.ip = ip
|
93
|
+
end
|
94
|
+
|
95
|
+
def mtu(mtu)
|
96
|
+
delegated.mtu = mtu
|
97
|
+
end
|
98
|
+
|
99
|
+
def bootproto(bootproto)
|
100
|
+
delegated.bootproto = bootproto
|
101
|
+
end
|
102
|
+
|
103
|
+
def network(network)
|
104
|
+
delegated.network = get_collection_item(:network, network)
|
105
|
+
end
|
106
|
+
|
107
|
+
def netmask(netmask)
|
108
|
+
delegated.network.netmask = netmask
|
109
|
+
end
|
110
|
+
|
111
|
+
def gateway(gateway)
|
112
|
+
delegated.network.gateway = gateway
|
113
|
+
end
|
114
|
+
|
115
|
+
def nameserver(nameserver)
|
116
|
+
delegated.network.nameservers << nameserver
|
117
|
+
end
|
118
|
+
|
119
|
+
def search_path(search_path)
|
120
|
+
delegated.network.search_paths << search_path
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Layout < Base
|
4
|
+
attr_accessor :zerombr
|
5
|
+
attr_accessor :clearpart
|
6
|
+
attr_accessor :partitions
|
7
|
+
attr_accessor :volume_groups
|
8
|
+
# attr_accessor :raid_groups
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@zerombr = false
|
12
|
+
@clearpart = false
|
13
|
+
@partitions = Array.new
|
14
|
+
@volume_groups = Array.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def validate!
|
18
|
+
if partitions.empty?
|
19
|
+
fail SyntaxError, 'You must supply a partition block'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def hashify
|
24
|
+
{
|
25
|
+
'partitions' => partitions.map{|p| p.hashify},
|
26
|
+
'volume_groups' => volume_groups.map{|v| v.hashify}
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
class LayoutDelegator < Stork::Resource::Delegator
|
31
|
+
flag :zerombr
|
32
|
+
flag :clearpart
|
33
|
+
|
34
|
+
def partition(name, options = {}, &block)
|
35
|
+
fail SyntaxError, 'You must supply a block to partition' unless block_given?
|
36
|
+
@delegated.partitions << Partition.build(name, options, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
alias_method :part, :partition
|
40
|
+
|
41
|
+
def volume_group(name, options = {}, &block)
|
42
|
+
fail SyntaxError, 'You must supply a block to volume_group' unless block_given?
|
43
|
+
@delegated.volume_groups << VolumeGroup.build(name, options, &block)
|
44
|
+
end
|
45
|
+
|
46
|
+
alias_method :volgroup, :volume_group
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class LogicalVolume < Base
|
4
|
+
attr_accessor :path
|
5
|
+
attr_accessor :size
|
6
|
+
attr_accessor :type
|
7
|
+
attr_accessor :primary
|
8
|
+
attr_accessor :grow
|
9
|
+
attr_accessor :recommended
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@size = 1
|
13
|
+
@type = 'ext4'
|
14
|
+
@grow = false
|
15
|
+
@recommended = true
|
16
|
+
@path = '/'
|
17
|
+
end
|
18
|
+
|
19
|
+
def hashify
|
20
|
+
{
|
21
|
+
'path' => path,
|
22
|
+
'size' => size,
|
23
|
+
'type' => type,
|
24
|
+
'primary' => primary,
|
25
|
+
'grow' => grow,
|
26
|
+
'recommended' => recommended
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
class LogicalVolumeDelegator < Stork::Resource::Delegator
|
31
|
+
flag :grow
|
32
|
+
flag :recommended
|
33
|
+
|
34
|
+
def path(path)
|
35
|
+
delegated.path = path
|
36
|
+
end
|
37
|
+
|
38
|
+
def size(size)
|
39
|
+
delegated.size = size
|
40
|
+
delegated.recommended = false
|
41
|
+
end
|
42
|
+
|
43
|
+
def type(type)
|
44
|
+
delegated.type = type
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Network < Base
|
4
|
+
attr_accessor :netmask
|
5
|
+
attr_accessor :gateway
|
6
|
+
attr_accessor :nameservers
|
7
|
+
attr_accessor :search_paths
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@netmask = "255.255.255.0"
|
11
|
+
@gateway = nil
|
12
|
+
@nameservers = Array.new
|
13
|
+
@search_paths = Array.new
|
14
|
+
end
|
15
|
+
|
16
|
+
class NetworkDelegator < Stork::Resource::Delegator
|
17
|
+
def netmask(netmask)
|
18
|
+
delegated.netmask = netmask
|
19
|
+
end
|
20
|
+
|
21
|
+
def gateway(gateway)
|
22
|
+
delegated.gateway = gateway
|
23
|
+
end
|
24
|
+
|
25
|
+
def nameserver(nameserver)
|
26
|
+
delegated.nameservers << nameserver
|
27
|
+
end
|
28
|
+
|
29
|
+
def search_path(search_path)
|
30
|
+
delegated.search_paths << search_path
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Partition < Base
|
4
|
+
attr_accessor :size
|
5
|
+
attr_accessor :type
|
6
|
+
attr_accessor :primary
|
7
|
+
attr_accessor :grow
|
8
|
+
attr_accessor :recommended
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@size = 1
|
12
|
+
@type = 'ext4'
|
13
|
+
@grow = false
|
14
|
+
@primary = false
|
15
|
+
@recommended = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def hashify
|
19
|
+
{
|
20
|
+
'path' => path,
|
21
|
+
'size' => size,
|
22
|
+
'type' => type,
|
23
|
+
'primary' => primary,
|
24
|
+
'grow' => grow,
|
25
|
+
'recommended' => recommended
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
alias_method :path, :name
|
30
|
+
|
31
|
+
class PartitionDelegator < Stork::Resource::Delegator
|
32
|
+
flag :primary
|
33
|
+
flag :grow
|
34
|
+
flag :recommended
|
35
|
+
|
36
|
+
def size(size)
|
37
|
+
delegated.size = size
|
38
|
+
delegated.recommended = false
|
39
|
+
end
|
40
|
+
|
41
|
+
def type(type)
|
42
|
+
delegated.type = type
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Password
|
4
|
+
def random_encrypted_password
|
5
|
+
salt = rand(36**8).to_s(36)
|
6
|
+
random_password.crypt('$6$' + salt)
|
7
|
+
end
|
8
|
+
|
9
|
+
def random_password
|
10
|
+
SecureRandom.urlsafe_base64(40)
|
11
|
+
end
|
12
|
+
|
13
|
+
def value
|
14
|
+
random_encrypted_password
|
15
|
+
end
|
16
|
+
|
17
|
+
def locked?
|
18
|
+
false
|
19
|
+
end
|
20
|
+
|
21
|
+
def encrypted
|
22
|
+
true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Repo < Base
|
4
|
+
attr_accessor :baseurl
|
5
|
+
attr_accessor :mirrorlist
|
6
|
+
|
7
|
+
def setup
|
8
|
+
@baseurl = options.key?(:baseurl) ? options[:baseurl] : nil
|
9
|
+
@mirrorlist = options.key?(:mirrorlist) ? options[:mirrorlist] : nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate!
|
13
|
+
unless baseurl || mirrorlist
|
14
|
+
fail SyntaxError, 'One of baseurl or mirrorlist must be specified.'
|
15
|
+
end
|
16
|
+
|
17
|
+
if baseurl && mirrorlist
|
18
|
+
fail SyntaxError, 'You may use only baseurl or mirrorlist but not both.'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def is_local?
|
23
|
+
!(baseurl && mirrorlist)
|
24
|
+
end
|
25
|
+
|
26
|
+
class RepoDelegator < Stork::Resource::Delegator ; end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Snippet
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :content
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@name = File.basename(path, '.erb')
|
9
|
+
@content = read_content(path)
|
10
|
+
end
|
11
|
+
|
12
|
+
alias_method :id, :name
|
13
|
+
|
14
|
+
private
|
15
|
+
def read_content(path)
|
16
|
+
File.read(path)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Template
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :content
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@name = File.basename(path, '.ks.erb')
|
9
|
+
@content = read_content(path)
|
10
|
+
end
|
11
|
+
|
12
|
+
def hashify
|
13
|
+
{'name' => name}
|
14
|
+
end
|
15
|
+
|
16
|
+
alias_method :id, :name
|
17
|
+
|
18
|
+
private
|
19
|
+
def read_content(path)
|
20
|
+
File.read(path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class Timezone < Base
|
4
|
+
attr_accessor :utc
|
5
|
+
attr_accessor :ntp
|
6
|
+
attr_accessor :ntpservers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@utc = false
|
10
|
+
@ntp = true
|
11
|
+
@ntpservers = %w(
|
12
|
+
0.pool.ntp.org
|
13
|
+
1.pool.ntp.org
|
14
|
+
2.pool.ntp.org
|
15
|
+
3.pool.ntp.org
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
alias_method :zone, :name
|
20
|
+
|
21
|
+
class TimezoneDelegator < Stork::Resource::Delegator
|
22
|
+
flag :utc
|
23
|
+
flag :ntp
|
24
|
+
|
25
|
+
def ntpserver(ntpserver)
|
26
|
+
delegated.ntpservers << ntpserver
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Stork
|
2
|
+
module Resource
|
3
|
+
class VolumeGroup < Base
|
4
|
+
attr_reader :name
|
5
|
+
attr_accessor :partition
|
6
|
+
attr_accessor :logical_volumes
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@partition = options.key?(:part) ? options[:part] : nil
|
10
|
+
@logical_volumes = Array.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def hashify
|
14
|
+
{
|
15
|
+
'partition' => partition,
|
16
|
+
'logical_volumes' => logical_volumes.map{|l| l.hashify}
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
class VolumeGroupDelegator < Stork::Resource::Delegator
|
21
|
+
def partition(partition)
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
def logical_volume(name, options = {}, &block)
|
26
|
+
@delegated.logical_volumes << LogicalVolume.build(name, options, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'stork/resource/delegator'
|
2
|
+
require 'stork/resource/base'
|
3
|
+
require 'stork/resource/chef'
|
4
|
+
require 'stork/resource/distro'
|
5
|
+
require 'stork/resource/partition'
|
6
|
+
require 'stork/resource/logical_volume'
|
7
|
+
require 'stork/resource/volume_group'
|
8
|
+
require 'stork/resource/layout'
|
9
|
+
require 'stork/resource/network'
|
10
|
+
require 'stork/resource/interface'
|
11
|
+
require 'stork/resource/firewall'
|
12
|
+
require 'stork/resource/password'
|
13
|
+
require 'stork/resource/timezone'
|
14
|
+
require 'stork/resource/snippet'
|
15
|
+
require 'stork/resource/template'
|
16
|
+
require 'stork/resource/repo'
|
17
|
+
require 'stork/resource/host'
|
@@ -0,0 +1,127 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
|
3
|
+
module Stork
|
4
|
+
module Server
|
5
|
+
class Application < Sinatra::Base
|
6
|
+
configure do
|
7
|
+
enable :logging
|
8
|
+
mime_type :plain, 'text/plain'
|
9
|
+
mime_type :json, 'application/json'
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
logger.datetime_format = '%Y/%m/%d @ %H:%M:%S '
|
14
|
+
logger.level = Logger::INFO
|
15
|
+
end
|
16
|
+
|
17
|
+
get '/' do
|
18
|
+
info 'GET /'
|
19
|
+
json_halt 200, 200, "Stork Version #{VERSION} - #{CODENAME}"
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/api/v1/hosts' do
|
23
|
+
h = {'hosts' => hosts.hashify}
|
24
|
+
json_halt_ok_with_content(h.to_json)
|
25
|
+
end
|
26
|
+
|
27
|
+
get '/api/v1/host/:host' do |host|
|
28
|
+
h = hosts.get(host)
|
29
|
+
json_halt_ok_with_content(h.hashify.to_json)
|
30
|
+
end
|
31
|
+
|
32
|
+
get '/host/:host' do |host|
|
33
|
+
info "#{host} requested kickstart"
|
34
|
+
|
35
|
+
h = hosts.get(host)
|
36
|
+
|
37
|
+
if h
|
38
|
+
# hmm, should the host deploy?
|
39
|
+
ks = Stork::Deploy::InstallScript.new(h) # we will be passing the type in shortly
|
40
|
+
content_type :plain
|
41
|
+
ks.render
|
42
|
+
else
|
43
|
+
json_halt_not_found
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
get '/host/:host/installed' do |host|
|
48
|
+
info "#{host} has notified completed install"
|
49
|
+
h = hosts.get(host)
|
50
|
+
|
51
|
+
if h
|
52
|
+
set_localboot(h)
|
53
|
+
json_halt_ok
|
54
|
+
else
|
55
|
+
json_halt_not_found
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
get '/host/:host/install' do |host|
|
60
|
+
info "install requested for #{host}"
|
61
|
+
h = hosts.get(host)
|
62
|
+
|
63
|
+
if h
|
64
|
+
set_install(h)
|
65
|
+
json_halt_ok
|
66
|
+
else
|
67
|
+
json_halt_not_found
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
not_found do
|
72
|
+
json_halt_not_found
|
73
|
+
end
|
74
|
+
|
75
|
+
helpers do
|
76
|
+
def hosts
|
77
|
+
@hosts ||= settings.collection.hosts
|
78
|
+
end
|
79
|
+
|
80
|
+
def config
|
81
|
+
@config ||= settings.config
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_localboot(host)
|
85
|
+
pxe(host).localboot
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_install(host)
|
89
|
+
pxe(host).install
|
90
|
+
end
|
91
|
+
|
92
|
+
def pxe(host)
|
93
|
+
Stork::PXE.new(host, host.stork, config.port)
|
94
|
+
end
|
95
|
+
|
96
|
+
def info(msg)
|
97
|
+
logger.info "[#{request.ip}] INFO: #{msg}"
|
98
|
+
end
|
99
|
+
|
100
|
+
def json_halt(request_status, op_status, message)
|
101
|
+
content_type :json
|
102
|
+
halt request_status, { 'Content-Type' => 'application/json' }, "{ \"status\":\"#{op_status}\", \"message\": \"#{message}\" }"
|
103
|
+
end
|
104
|
+
|
105
|
+
def json_halt_ok
|
106
|
+
content_type :json
|
107
|
+
json_halt 200, 200, 'OK'
|
108
|
+
end
|
109
|
+
|
110
|
+
def json_halt_ok_with_content(content)
|
111
|
+
content_type :json
|
112
|
+
halt 200, { 'Content-Type' => 'application/json' }, content
|
113
|
+
end
|
114
|
+
|
115
|
+
def json_halt_internal_error
|
116
|
+
content_type :json
|
117
|
+
json_halt 500, 500, 'Internal error'
|
118
|
+
end
|
119
|
+
|
120
|
+
def json_halt_not_found
|
121
|
+
content_type :json
|
122
|
+
json_halt 404, 404, 'not found'
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'json'
|
3
|
+
require 'rack'
|
4
|
+
require 'thin'
|
5
|
+
|
6
|
+
module Stork
|
7
|
+
module Server
|
8
|
+
class Control
|
9
|
+
def self.start(configuration, collection)
|
10
|
+
puts "Starting stork server on port #{configuration.port}."
|
11
|
+
app = Stork::Server::Application
|
12
|
+
app.set :collection, collection
|
13
|
+
app.set :config, configuration
|
14
|
+
|
15
|
+
@thin = Thin::Server.new(configuration.bind, configuration.port, app)
|
16
|
+
@thin.tag = "Stork #{VERSION}"
|
17
|
+
unless ENV['RACK_ENV'] == 'test'
|
18
|
+
@thin.pid_file = configuration.pid_file
|
19
|
+
@thin.log_file = configuration.log_file
|
20
|
+
@thin.daemonize
|
21
|
+
else
|
22
|
+
puts '!!! Running in test mode'
|
23
|
+
end
|
24
|
+
@thin.start
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.stop(configuration, collection)
|
28
|
+
puts 'Stoping the stork server.'
|
29
|
+
Thin::Server.kill(configuration.pid_file)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.restart(configuration, collection)
|
33
|
+
stop(configuration, collection)
|
34
|
+
start(configuration, collection)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/stork.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'json'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require 'stork/version'
|
6
|
+
require 'stork/configuration'
|
7
|
+
require 'stork/collections'
|
8
|
+
require 'stork/resources'
|
9
|
+
|
10
|
+
require 'stork/builder'
|
11
|
+
|
12
|
+
require 'stork/deploy/command'
|
13
|
+
require 'stork/deploy/section'
|
14
|
+
require 'stork/deploy/snippet_binding'
|
15
|
+
require 'stork/deploy/kickstart_binding'
|
16
|
+
require 'stork/deploy/install_script'
|
17
|
+
|
18
|
+
require 'stork/pxe'
|
19
|
+
|
20
|
+
require 'stork/server/application'
|
21
|
+
require 'stork/server/control'
|
22
|
+
|
23
|
+
require 'stork/plugin'
|
24
|
+
Dir[File.join('./lib/stork/client/plugins', '*.rb')].each do |plugin|
|
25
|
+
require plugin
|
26
|
+
|
27
|
+
Stork.add_plugin(plugin)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Also make sure we allow a .stork/plugins dir
|