capazon 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +4 -0
- data/Manifest.txt +0 -1
- data/README.txt +8 -12
- data/lib/capazon/configuration.rb +1 -4
- data/lib/capazon/tasks.rb +103 -103
- data/lib/capazon/version.rb +2 -2
- metadata +2 -3
- data/lib/capazon/meta_tasks.rb +0 -82
data/CHANGELOG.txt
CHANGED
data/Manifest.txt
CHANGED
data/README.txt
CHANGED
@@ -34,18 +34,14 @@ Capistrano tasks to manage Amazon EC2 Images.
|
|
34
34
|
* <em>All tasks <b>require</b> aws_access_key_id and aws_secret_access_key.</em>
|
35
35
|
* <em>All tasks optionally take environment variables in lieu of capistrano configuration variables.</em>
|
36
36
|
|
37
|
-
[+create_keypair+] Create a keypair aws_keypair_name and write out the generate private key to aws_private_key_path.
|
38
|
-
[+delete_keypair+] Deletes keypair aws_keypair_name.
|
39
|
-
[+describe_keypairs+] Describes keypairs.
|
40
|
-
[+describe_images+] Describes AMIs you have privilege to execute.
|
41
|
-
[+run_instance+] Runs an instance of aws_ami_id with access available via aws_keypair_name.
|
42
|
-
[+terminate_instance+] Terminates aws_instance_id.
|
43
|
-
[+describe_instances+] Describes running AMIs.
|
44
|
-
[+authorize_web_and_ssh_access+] Opens tcp access on port 80 and 22 to the aws_security_group.
|
45
|
-
|
46
|
-
==== Experimental Tasks
|
47
|
-
|
48
|
-
[+run_and_configure_instance+] Runs an instance of aws_ami_id with access available via aws_keypair_name, and - very experimentally - changes the root password, adds a user, gives that user sudo rights, then writes out a new deploy.rb to allow this new instance to be used with the 'deprec' gem.
|
37
|
+
[+ec2:create_keypair+] Create a keypair aws_keypair_name and write out the generate private key to aws_private_key_path.
|
38
|
+
[+ec2:delete_keypair+] Deletes keypair aws_keypair_name.
|
39
|
+
[+ec2:describe_keypairs+] Describes keypairs.
|
40
|
+
[+ec2:describe_images+] Describes AMIs you have privilege to execute.
|
41
|
+
[+ec2:run_instance+] Runs an instance of aws_ami_id with access available via aws_keypair_name.
|
42
|
+
[+ec2:terminate_instance+] Terminates aws_instance_id.
|
43
|
+
[+ec2:describe_instances+] Describes running AMIs.
|
44
|
+
[+ec2:authorize_web_and_ssh_access+] Opens tcp access on port 80 and 22 to the aws_security_group.
|
49
45
|
|
50
46
|
== Meta
|
51
47
|
|
@@ -1,10 +1,7 @@
|
|
1
1
|
# Author:: Jesse Newland (jnewland@gmail.com)
|
2
2
|
# Copyright:: Copyright (c) 2007 Jesse Newland
|
3
3
|
# License:: Distributes under the same terms as Ruby
|
4
|
-
|
5
|
-
Capistrano.configuration(:must_exist).load do
|
6
|
-
require 'deprec/recipes'
|
7
|
-
|
4
|
+
Capistrano::Configuration.instance.load do
|
8
5
|
set :aws_ami_id, "ami-e4b6538d"
|
9
6
|
set :aws_security_group, "default"
|
10
7
|
end
|
data/lib/capazon/tasks.rb
CHANGED
@@ -2,111 +2,111 @@
|
|
2
2
|
# Author:: Jesse Newland (jnewland@gmail.com)
|
3
3
|
# Copyright:: Copyright (c) 2007 Jesse Newland
|
4
4
|
# License:: Distributes under the same terms as Ruby
|
5
|
+
Capistrano::Configuration.instance.load do
|
6
|
+
namespace :ec2 do
|
7
|
+
desc <<-DESC
|
8
|
+
Create a keypair AWS_KEYPAIR_NAME and
|
9
|
+
write out the generate private key to AWS_PRIVATE_KEY_PATH.
|
10
|
+
Requires Amazon authorization credentials:
|
11
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
12
|
+
DESC
|
13
|
+
task :create_keypair do
|
14
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
15
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
16
|
+
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
17
|
+
private_key_path = ENV['AWS_PRIVATE_KEY_PATH'] || aws_private_key_path
|
18
|
+
capazon.setup_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name, private_key_path)
|
19
|
+
end
|
5
20
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
17
|
-
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
18
|
-
private_key_path = ENV['AWS_PRIVATE_KEY_PATH'] || aws_private_key_path
|
19
|
-
capazon.setup_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name, private_key_path)
|
20
|
-
end
|
21
|
-
|
22
|
-
desc <<-DESC
|
23
|
-
Deletes keypair AWS_KEYPAIR_NAME.
|
24
|
-
Requires Amazon authorization credentials:
|
25
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
26
|
-
DESC
|
27
|
-
task :delete_keypair do
|
28
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
29
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
30
|
-
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
31
|
-
capazon.delete_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name)
|
32
|
-
end
|
33
|
-
|
34
|
-
desc <<-DESC
|
35
|
-
Runs an instance of AWS_AMI_ID with AWS_KEYPAIR_NAME.
|
36
|
-
Requires Amazon authorization credentials:
|
37
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
38
|
-
DESC
|
39
|
-
task :run_instance do
|
40
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
41
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
42
|
-
ami_id = ENV['AWS_AMI_ID'] || aws_ami_id
|
43
|
-
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
44
|
-
instance_desc = capazon.run_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},ami_id,keypair_name)
|
45
|
-
puts instance_desc.join("\t")
|
46
|
-
end
|
47
|
-
|
48
|
-
desc <<-DESC
|
49
|
-
Opens tcp access on port 80 and 22 to the specified security group.
|
50
|
-
Requires Amazon authorization credentials:
|
51
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
52
|
-
DESC
|
53
|
-
task :authorize_web_and_ssh_access do
|
54
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
55
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
56
|
-
group_name = ENV['AWS_SECURITY_GROUP'] || (aws_security_group rescue "default")
|
57
|
-
capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","80","80","0.0.0.0/0")
|
58
|
-
capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","22","22","0.0.0.0/0")
|
59
|
-
end
|
60
|
-
|
61
|
-
desc <<-DESC
|
62
|
-
Terminates AWS_INSTANCE_ID.
|
63
|
-
Requires Amazon authorization credentials:
|
64
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
65
|
-
DESC
|
66
|
-
task :terminate_instance do
|
67
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
68
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
69
|
-
instance_id = ENV['AWS_INSTANCE_ID'] || aws_instance_id
|
70
|
-
respnse = capazon.terminate_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, instance_id)
|
71
|
-
puts respnse.join("\t")
|
72
|
-
end
|
73
|
-
|
74
|
-
desc <<-DESC
|
75
|
-
Describes keypairs.
|
76
|
-
Requires Amazon authorization credentials:
|
77
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
78
|
-
DESC
|
79
|
-
task :describe_keypairs do
|
80
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
81
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
82
|
-
capazon.describe_keypairs({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |keypair|
|
83
|
-
puts keypair.join("\t")
|
21
|
+
desc <<-DESC
|
22
|
+
Deletes keypair AWS_KEYPAIR_NAME.
|
23
|
+
Requires Amazon authorization credentials:
|
24
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
25
|
+
DESC
|
26
|
+
task :delete_keypair do
|
27
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
28
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
29
|
+
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
30
|
+
capazon.delete_keypair({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, keypair_name)
|
84
31
|
end
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
32
|
+
|
33
|
+
desc <<-DESC
|
34
|
+
Runs an instance of AWS_AMI_ID with AWS_KEYPAIR_NAME.
|
35
|
+
Requires Amazon authorization credentials:
|
36
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
37
|
+
DESC
|
38
|
+
task :run_instance do
|
39
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
40
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
41
|
+
ami_id = ENV['AWS_AMI_ID'] || aws_ami_id
|
42
|
+
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
43
|
+
instance_desc = capazon.run_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},ami_id,keypair_name)
|
44
|
+
puts instance_desc.join("\t")
|
97
45
|
end
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
46
|
+
|
47
|
+
desc <<-DESC
|
48
|
+
Opens tcp access on port 80 and 22 to the specified security group.
|
49
|
+
Requires Amazon authorization credentials:
|
50
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
51
|
+
DESC
|
52
|
+
task :authorize_web_and_ssh_access do
|
53
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
54
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
55
|
+
group_name = ENV['AWS_SECURITY_GROUP'] || (aws_security_group rescue "default")
|
56
|
+
capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","80","80","0.0.0.0/0")
|
57
|
+
capazon.authorize_access({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},group_name,"tcp","22","22","0.0.0.0/0")
|
58
|
+
end
|
59
|
+
|
60
|
+
desc <<-DESC
|
61
|
+
Terminates AWS_INSTANCE_ID.
|
62
|
+
Requires Amazon authorization credentials:
|
63
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
64
|
+
DESC
|
65
|
+
task :terminate_instance do
|
66
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
67
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
68
|
+
instance_id = ENV['AWS_INSTANCE_ID'] || aws_instance_id
|
69
|
+
respnse = capazon.terminate_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}, instance_id)
|
70
|
+
puts respnse.join("\t")
|
71
|
+
end
|
72
|
+
|
73
|
+
desc <<-DESC
|
74
|
+
Describes keypairs.
|
75
|
+
Requires Amazon authorization credentials:
|
76
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
77
|
+
DESC
|
78
|
+
task :describe_keypairs do
|
79
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
80
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
81
|
+
capazon.describe_keypairs({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |keypair|
|
82
|
+
puts keypair.join("\t")
|
83
|
+
end
|
110
84
|
end
|
111
|
-
|
85
|
+
|
86
|
+
desc <<-DESC
|
87
|
+
Describes running AMIs.
|
88
|
+
Requires Amazon authorization credentials:
|
89
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
90
|
+
DESC
|
91
|
+
task :describe_instances do
|
92
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
93
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
94
|
+
capazon.describe_instances({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |instance|
|
95
|
+
puts instance.join("\t")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc <<-DESC
|
100
|
+
Describes AMIs you have privilege to execute.
|
101
|
+
Requires Amazon authorization credentials:
|
102
|
+
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAME
|
103
|
+
DESC
|
104
|
+
task :describe_images do
|
105
|
+
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
106
|
+
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
107
|
+
capazon.describe_images({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key}).each do |image|
|
108
|
+
puts image.join("\t")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
112
|
end
|
data/lib/capazon/version.rb
CHANGED
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.2
|
|
3
3
|
specification_version: 1
|
4
4
|
name: capazon
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.
|
7
|
-
date: 2007-
|
6
|
+
version: 0.2.0
|
7
|
+
date: 2007-04-30 00:00:00 -04:00
|
8
8
|
summary: A Capistrano extension library to manage Amazon EC2 instances
|
9
9
|
require_paths:
|
10
10
|
- lib
|
@@ -37,7 +37,6 @@ files:
|
|
37
37
|
- examples/deploy.rb
|
38
38
|
- lib/capazon/capistrano_plugin.rb
|
39
39
|
- lib/capazon/configuration.rb
|
40
|
-
- lib/capazon/meta_tasks.rb
|
41
40
|
- lib/capazon/tasks.rb
|
42
41
|
- lib/capazon/version.rb
|
43
42
|
- lib/capazon.rb
|
data/lib/capazon/meta_tasks.rb
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
# Author:: Jesse Newland (jnewland@gmail.com)
|
2
|
-
# Copyright:: Copyright (c) 2007 Jesse Newland
|
3
|
-
# License:: Distributes under the same terms as Ruby
|
4
|
-
|
5
|
-
Capistrano.configuration(:must_exist).load do
|
6
|
-
desc <<-DESC
|
7
|
-
Runs an instance of AWS_AMI_ID with AWS_KEYPAIR_NAME, and - very experimentally - changes the root password, adds a user, gives that user sudo rights, then writes out a new deploy.rb to allow this new instance to be used with the 'deprec' gem.
|
8
|
-
Requires Amazon authorization credentials:
|
9
|
-
AWS_ACCESS_KEY_ID, AWS_KEYPAIR_NAMEE
|
10
|
-
DESC
|
11
|
-
task :run_and_configure_instance do
|
12
|
-
create_keypair
|
13
|
-
|
14
|
-
access_key_id = ENV['AWS_ACCESS_KEY_ID'] || aws_access_key_id
|
15
|
-
secret_access_key = ENV['AWS_SECRET_ACCESS_KEY'] || aws_secret_access_key
|
16
|
-
ami_id = ENV['AWS_AMI_ID'] || aws_ami_id
|
17
|
-
keypair_name = ENV['AWS_KEYPAIR_NAME'] || aws_keypair_name
|
18
|
-
private_key_path = ENV['AWS_PRIVATE_KEY_PATH'] || aws_private_key_path
|
19
|
-
instance_desc = capazon.run_instance({:AWS_ACCESS_KEY_ID => access_key_id, :AWS_SECRET_ACCESS_KEY => secret_access_key},ami_id,keypair_name)
|
20
|
-
|
21
|
-
authorize_web_and_ssh_access
|
22
|
-
|
23
|
-
puts "Waiting one additional minute for startup..."
|
24
|
-
sleep 60
|
25
|
-
|
26
|
-
#change password
|
27
|
-
puts "Connecting to #{instance_desc[3]}..."
|
28
|
-
puts "Please create a secure root password"
|
29
|
-
system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} passwd"
|
30
|
-
puts "Creating #{user} user"
|
31
|
-
system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'groupadd wheel;useradd -m -G wheel -s /bin/bash #{user};passwd #{user}'"
|
32
|
-
puts "Adding wheel group to sudoers"
|
33
|
-
system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'chmod 640 /etc/sudoers; echo -e \"#{user}\tALL=(ALL)\tALL\" >> /etc/sudoers;chmod 440 /etc/sudoers'"
|
34
|
-
# puts "Setting up loopback interface"
|
35
|
-
# system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'echo -e \"127.0.0.1\tlocalhost\" > /etc/hosts;echo -e \"iface lo inet loopback\" >> /etc/network/interfaces;ifup lo'"
|
36
|
-
# puts "Appending source list"
|
37
|
-
# system "ssh -o StrictHostKeyChecking=no -i #{private_key_path} root@#{instance_desc[3]} 'echo -e \"deb http://archive.ubuntu.com/ubuntu edgy main restricted universe multiverse\ndeb http://archive.ubuntu.com/ubuntu/ edgy-updates main restricted universe multiverse\" >/etc/apt/sources.list'"
|
38
|
-
|
39
|
-
#append capazon config info
|
40
|
-
|
41
|
-
original = File.open("config/deploy.rb")
|
42
|
-
backup = File.open("config/deploy.rb.capazon", "w")
|
43
|
-
while original.gets do
|
44
|
-
backup.print $_
|
45
|
-
end
|
46
|
-
backup.close
|
47
|
-
original.close
|
48
|
-
|
49
|
-
puts "Overwriting capistrano configuration..."
|
50
|
-
system "yes | deprec --apply-to . --name #{application} --domain #{instance_desc[3]}"
|
51
|
-
|
52
|
-
puts "Updating deprec config with amazon information..."
|
53
|
-
|
54
|
-
deprec = File.open("config/deploy.rb")
|
55
|
-
capazon = File.open("config/deploy.rb.capazon")
|
56
|
-
deprec_capazon = File.open("config/deploy.rb.deprec_capazon", "w")
|
57
|
-
|
58
|
-
while deprec.gets do
|
59
|
-
if $. == 1 then
|
60
|
-
deprec_capazon.print "#Capazon Configuration\n"
|
61
|
-
deprec_capazon.print "\nset :aws_instance_id, '#{instance_desc[1]}'\n\n"
|
62
|
-
while capazon.gets do
|
63
|
-
unless $. == 1 || $_ == nil
|
64
|
-
deprec_capazon.print $_
|
65
|
-
end
|
66
|
-
end
|
67
|
-
end
|
68
|
-
unless $_ == nil || /^set :repository/.match($_) || /^set :application/.match($_) || /XXX/.match($_)
|
69
|
-
deprec_capazon.print $_
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
capazon.close
|
74
|
-
deprec.close
|
75
|
-
deprec_capazon.close
|
76
|
-
File.rename("config/deploy.rb", "config/deploy.rb.deprec")
|
77
|
-
File.rename("config/deploy.rb.deprec_capazon", "config/deploy.rb")
|
78
|
-
|
79
|
-
puts "Done!"
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|