Commit | Line | Data |
c9ecd647 |
1 | package Oyster::Provision::Rackspace; |
3ded6347 |
2 | use Moose::Role; |
4bd125ea |
3 | use Net::RackSpace::CloudServers; |
4 | use Net::RackSpace::CloudServers::Server; |
5 | use MIME::Base64; |
3ded6347 |
6 | |
d29be7cc |
7 | # TODO http://failverse.com/manually-creating-a-cloud-server-from-a-cloud-files-image/ |
8 | # in order to use an already created image to build the server, a la EC2 way |
9 | |
3ded6347 |
10 | requires 'config'; |
11 | |
189564ce |
12 | has 'api_username' => ( is => 'ro', isa => 'Str', required => 1, lazy_build => 1); |
13 | sub _build_api_username { |
de5283c8 |
14 | my $self = shift; |
758d921f |
15 | return $ENV{CLOUDSERVERS_USER} if exists $ENV{CLOUDSERVERS_USER}; |
a9e65cee |
16 | return $self->config->{api_username} |
17 | or die "Need api_username or CLOUDSERVERS_USER in environment"; |
e4c30324 |
18 | } |
8a0402ec |
19 | |
189564ce |
20 | has 'api_password' => ( is => 'ro', isa => 'Str', required => 1, lazy_build => 1); |
21 | sub _build_api_password { |
de5283c8 |
22 | my $self = shift; |
758d921f |
23 | return $ENV{CLOUDSERVERS_KEY} if exists $ENV{CLOUDSERVERS_KEY}; |
a9e65cee |
24 | return $self->config->{api_password} |
25 | or die "Need api_password or CLOUDSERVERS_KEY in environment"; |
189564ce |
26 | } |
4bd125ea |
27 | |
1f1bb35e |
28 | has '_rs' => ( is => 'rw', isa => 'Net::RackSpace::CloudServers', default => sub { |
4bd125ea |
29 | my $self = shift; |
30 | my $rs = Net::RackSpace::CloudServers->new( |
31 | user => $self->api_username, |
8a0402ec |
32 | key => $self->api_password, |
4bd125ea |
33 | ); |
34 | $rs; |
35 | }); |
36 | |
3ded6347 |
37 | sub create { |
38 | my $self = shift; |
39 | |
4bd125ea |
40 | # Do nothing if the server named $self->name already exists |
41 | return if scalar grep { $_->name eq $self->name } $self->_rs->get_server(); |
42 | |
43 | # Check the ssh pub key exists and is <10K |
370470b2 |
44 | die "SSH pubkey needs to exist" if !-f $self->pub_ssh; |
4bd125ea |
45 | my $pub_ssh = do { |
46 | local $/=undef; |
47 | open my $fh, '<', $self->pub_ssh or die "Cannot open ", $self->pub_ssh, ": $!"; |
48 | my $_data = <$fh>; |
49 | close $fh or die "Cannot close ", $self->pub_ssh, ": $!"; |
50 | $_data; |
51 | }; |
370470b2 |
52 | die "SSH pubkey needs to be < 10KiB" if length $pub_ssh > 10*1024; |
4bd125ea |
53 | |
54 | # Build the server |
55 | my $server = Net::RackSpace::CloudServers::Server->new( |
6895749d |
56 | cloudservers => $self->_rs, |
57 | name => $self->name, |
58 | flavorid => $self->size, |
59 | imageid => $self->image, |
60 | personality => [ |
4bd125ea |
61 | { |
83928564 |
62 | path => '/root/.ssh/authorized_keys', |
4bd125ea |
63 | contents => encode_base64($pub_ssh), |
64 | }, |
6895749d |
65 | ], |
4bd125ea |
66 | ); |
355db0c8 |
67 | my $newserver = $server->create_server; |
68 | warn "Server root password: ", $newserver->adminpass, "\n"; |
4bd125ea |
69 | |
9e1b1d26 |
70 | do { |
71 | $|=1; |
72 | my @tmpservers = $self->_rs->get_server_detail(); |
73 | $server = ( grep { $_->name eq $self->name } @tmpservers )[0]; |
74 | print "\rServer status: ", ($server->status || '?'), " progress: ", ($server->progress || '?'); |
75 | if ( ( $server->status // '' ) ne 'ACTIVE' ) { |
76 | print " sleeping.."; |
77 | sleep 2; |
78 | } |
79 | } while ( ( $server->status // '' ) ne 'ACTIVE' ); |
80 | |
2bfa7038 |
81 | warn "Server public IP is: @{$server->public_address}\n"; |
4bd125ea |
82 | |
83 | # Connect to server and execute installation routines? |
84 | # Use Net::SSH? |
3ded6347 |
85 | } |
86 | |
3ded6347 |
87 | sub delete { |
88 | my $self = shift; |
89 | |
4bd125ea |
90 | # Die if the server named $self->name already exists |
91 | my ($server) = grep { $_->name eq $self->name } $self->_rs->get_server(); |
370470b2 |
92 | die "No such server: ", $self->name if !$server; |
4bd125ea |
93 | |
94 | # Goodbye cruel user! |
95 | $server->delete_server(); |
3ded6347 |
96 | } |
97 | |
98 | sub resize { |
99 | my $self = shift; |
100 | |
101 | $self->config(); |
102 | } |
c9ecd647 |
103 | |
104 | 1; |
dd69a60d |
105 | |
106 | __END__ |
107 | |
108 | =head1 NAME |
109 | |
110 | Oyster::Provision::Rackspace -- Provision your Oyster on Rackspace |
111 | |
112 | =head1 SYNOPSIS |
113 | |
114 | Use the Rackspace backend on your Oyster configuration file |
115 | |
116 | =head1 REQUIRED PARAMETERS |
117 | |
118 | The following are required to instantiate a backend: |
119 | |
120 | =over |
121 | |
4bd125ea |
122 | =item api_username |
123 | |
124 | The rackspace API username, or C<$ENV{RACKSPACE_USER}> will be used if that is |
125 | not given |
126 | |
8a0402ec |
127 | =item password |
128 | |
129 | This is your rackspace API Key |
4bd125ea |
130 | |
131 | The rackspace API key, or C<$ENV{RACKSPACE_KEY}> will be used if that is not |
132 | given |
133 | |
dd69a60d |
134 | =item name |
135 | |
136 | The name of your new/existing rackspace server. |
137 | |
138 | =item size |
139 | |
140 | The size ID of the rackspace server you want to create. |
141 | Use the following incantation to see them: |
142 | |
143 | perl -MNet::RackSpace::CloudServers -e' |
144 | $r=Net::RackSpace::CloudServers->new( |
145 | user=>$ENV{CLOUDSERVERS_USER}, |
146 | key=>$ENV{CLOUDSERVERS_KEY}, |
147 | ); |
148 | print map |
149 | { "id $_->{id} ram $_->{ram} disk $_->{disk}\n" } |
150 | $r->get_flavor_detail |
151 | ' |
152 | id 1 ram 256 disk 10 |
153 | id 2 ram 512 disk 20 |
154 | id 3 ram 1024 disk 40 |
155 | id 4 ram 2048 disk 80 |
156 | id 5 ram 4096 disk 160 |
157 | id 6 ram 8192 disk 320 |
158 | id 7 ram 15872 disk 620 |
159 | |
160 | =item image |
161 | |
162 | The image ID of the rackspace server you want to create. |
163 | Use the following incantation to see them: |
164 | |
165 | perl -MNet::RackSpace::CloudServers -e' |
166 | $r=Net::RackSpace::CloudServers->new( |
167 | user=>$ENV{CLOUDSERVERS_USER}, |
168 | key=>$ENV{CLOUDSERVERS_KEY}, |
169 | ); |
170 | print map |
171 | { "id $_->{id} name $_->{name}\n" } |
172 | $r->get_image_detail |
173 | ' |
174 | id 29 name Windows Server 2003 R2 SP2 x86 |
175 | id 69 name Ubuntu 10.10 (maverick) |
176 | id 41 name Oracle EL JeOS Release 5 Update 3 |
177 | id 40 name Oracle EL Server Release 5 Update 4 |
178 | id 187811 name CentOS 5.4 |
179 | id 4 name Debian 5.0 (lenny) |
180 | id 10 name Ubuntu 8.04.2 LTS (hardy) |
181 | id 23 name Windows Server 2003 R2 SP2 x64 |
182 | id 24 name Windows Server 2008 SP2 x64 |
183 | id 49 name Ubuntu 10.04 LTS (lucid) |
184 | id 14362 name Ubuntu 9.10 (karmic) |
185 | id 62 name Red Hat Enterprise Linux 5.5 |
186 | id 53 name Fedora 13 |
187 | id 17 name Fedora 12 |
188 | id 71 name Fedora 14 |
189 | id 31 name Windows Server 2008 SP2 x86 |
190 | id 51 name CentOS 5.5 |
191 | id 14 name Red Hat Enterprise Linux 5.4 |
192 | id 19 name Gentoo 10.1 |
193 | id 28 name Windows Server 2008 R2 x64 |
194 | id 55 name Arch 2010.05 |
195 | |
196 | Oyster only supports Linux images, specifically |
197 | Ubuntu 10.10 (maverick). |
198 | |
199 | =item pub_ssh |
200 | |
201 | The public ssh key you would like copied to the |
202 | new server's C</root/.ssh/authorized_keys> file |
203 | to allow you to ssh in the box without providing |
204 | a root password. |
205 | |
206 | =back |
207 | |
208 | =cut |