Ambiente » History » Version 45
Beraldo Leal, 07 Jun 2012 14:57
| 1 | 1 | Beraldo Leal | h1. Ambiente de Desenvolvimento |
|---|---|---|---|
| 2 | 1 | Beraldo Leal | |
| 3 | 1 | Beraldo Leal | h2. Lista de Servidores |
| 4 | 1 | Beraldo Leal | |
| 5 | 14 | Beraldo Leal | * educloud00 - 200.145.46.166 |
| 6 | 14 | Beraldo Leal | * educloud01 - 200.145.46.167 |
| 7 | 14 | Beraldo Leal | * educloud02 - 200.145.46.168 |
| 8 | 14 | Beraldo Leal | * educloud03 - 200.145.46.169 |
| 9 | 14 | Beraldo Leal | * educloud04 - 200.145.46.170 |
| 10 | 14 | Beraldo Leal | * educloud05 - 200.145.46.174 |
| 11 | 1 | Beraldo Leal | * educloud06 - 200.145.46.175 |
| 12 | 1 | Beraldo Leal | * educloud07 - 200.145.46.173 |
| 13 | 15 | Beraldo Leal | |
| 14 | 16 | Beraldo Leal | h3. Desabilitados |
| 15 | 16 | Beraldo Leal | |
| 16 | 15 | Beraldo Leal | * educloud05 - 200.145.46.171 |
| 17 | 15 | Beraldo Leal | * educloud06 - 200.145.46.172 |
| 18 | 3 | Beraldo Leal | |
| 19 | 37 | Beraldo Leal | h1. Installing OpenStack Identity Service - Keystone |
| 20 | 30 | Beraldo Leal | |
| 21 | 43 | Beraldo Leal | O Keystone é um projeto que provê serviços de "Identidade", "Token", "Catalog" and "Policy" para os componentes do OpenStack. O pacote *_keystone_* foi instalado no servidor _educloud01_. |
| 22 | 4 | Beraldo Leal | |
| 23 | 4 | Beraldo Leal | Este software é feito em python, e por sua vez instala a dependencia *_keystone-python_*, uma biblioteca em python para uso do próprio keystone. |
| 24 | 4 | Beraldo Leal | |
| 25 | 4 | Beraldo Leal | Os arquivos de configuração do keystone ficam em /etc/keystone e hoje ele está utilizando como um backend para armazenar os usuários uma base sqlite3, mas ele também permite que seja utilizado uma base LDAP. |
| 26 | 4 | Beraldo Leal | |
| 27 | 1 | Beraldo Leal | Além do daemon (servidor) foi instalado o cliente (também feito em python) *_python-keystoneclient_*. |
| 28 | 5 | Beraldo Leal | |
| 29 | 37 | Beraldo Leal | h2. Instalando e configurando o keystone |
| 30 | 5 | Beraldo Leal | |
| 31 | 1 | Beraldo Leal | <pre> |
| 32 | 18 | Beraldo Leal | # apt-get install keystone |
| 33 | 18 | Beraldo Leal | </pre> |
| 34 | 18 | Beraldo Leal | |
| 35 | 18 | Beraldo Leal | Delete the keystone.db file created in the /var/lib/keystone directory. |
| 36 | 18 | Beraldo Leal | |
| 37 | 18 | Beraldo Leal | <pre> |
| 38 | 18 | Beraldo Leal | # rm /var/lib/keystone/keystone.db |
| 39 | 18 | Beraldo Leal | </pre> |
| 40 | 18 | Beraldo Leal | |
| 41 | 18 | Beraldo Leal | Install mysql: |
| 42 | 18 | Beraldo Leal | |
| 43 | 18 | Beraldo Leal | <pre> |
| 44 | 18 | Beraldo Leal | # apt-get install python-mysqldb mysql-server |
| 45 | 11 | Beraldo Leal | </pre> |
| 46 | 19 | Beraldo Leal | |
| 47 | 19 | Beraldo Leal | Use sed to edit /etc/mysql/my.cnf to change bind-address from localhost |
| 48 | 19 | Beraldo Leal | (127.0.0.1) to any (0.0.0.0) and restart the mysql service, as root: |
| 49 | 19 | Beraldo Leal | |
| 50 | 19 | Beraldo Leal | <pre> |
| 51 | 19 | Beraldo Leal | # sed -i 's/127.0.0.1/0.0.0.0/g' /etc/mysql/my.cnf |
| 52 | 19 | Beraldo Leal | # service mysql restart |
| 53 | 19 | Beraldo Leal | </pre> |
| 54 | 19 | Beraldo Leal | |
| 55 | 19 | Beraldo Leal | To configure the MySQL database, create the keystone database. |
| 56 | 19 | Beraldo Leal | |
| 57 | 19 | Beraldo Leal | <pre> |
| 58 | 19 | Beraldo Leal | # mysql -u root -p |
| 59 | 19 | Beraldo Leal | mysql> CREATE DATABASE keystone; |
| 60 | 19 | Beraldo Leal | mysql> GRANT ALL ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystonepass'; |
| 61 | 19 | Beraldo Leal | mysql> FLUSH PRIVILEGES; |
| 62 | 19 | Beraldo Leal | mysql> quit; |
| 63 | 19 | Beraldo Leal | </pre> |
| 64 | 20 | Beraldo Leal | |
| 65 | 20 | Beraldo Leal | Edit _*keystone.conf*_ to use mysql: |
| 66 | 20 | Beraldo Leal | |
| 67 | 20 | Beraldo Leal | <pre> |
| 68 | 20 | Beraldo Leal | [sql] |
| 69 | 20 | Beraldo Leal | connection = mysql://keystone:keystonepass@192.168.69.1/keystone |
| 70 | 21 | Beraldo Leal | </pre> |
| 71 | 21 | Beraldo Leal | |
| 72 | 21 | Beraldo Leal | Change in _*keystone.conf*_ the ADMIN_TOKEN: |
| 73 | 21 | Beraldo Leal | |
| 74 | 20 | Beraldo Leal | <pre> |
| 75 | 21 | Beraldo Leal | admin_token = 012345SECRET99TOKEN012345 |
| 76 | 21 | Beraldo Leal | </pre> |
| 77 | 22 | Beraldo Leal | |
| 78 | 22 | Beraldo Leal | Restarte o keystone e inicialize o banco: |
| 79 | 22 | Beraldo Leal | |
| 80 | 22 | Beraldo Leal | <pre> |
| 81 | 22 | Beraldo Leal | # service keystone restart |
| 82 | 1 | Beraldo Leal | # keystone-manage db_sync |
| 83 | 22 | Beraldo Leal | </pre> |
| 84 | 23 | Beraldo Leal | |
| 85 | 37 | Beraldo Leal | h2. Configuring Services to work with Keystone |
| 86 | 23 | Beraldo Leal | |
| 87 | 23 | Beraldo Leal | Crie o arquivo _*/root/openstackrc*_, com o seguinte conteudo: |
| 88 | 23 | Beraldo Leal | |
| 89 | 23 | Beraldo Leal | <pre> |
| 90 | 23 | Beraldo Leal | export SERVICE_ENDPOINT=http://192.168.69.1:35357/v2.0/ |
| 91 | 23 | Beraldo Leal | export SERVICE_TOKEN=012345SECRET99TOKEN012345 |
| 92 | 23 | Beraldo Leal | </pre> |
| 93 | 23 | Beraldo Leal | |
| 94 | 23 | Beraldo Leal | Estas variaveis de ambiente sao uteis para evitar ficar passando as opcoes --token e --endpoint para os utilitarios de linha de comando. |
| 95 | 23 | Beraldo Leal | |
| 96 | 23 | Beraldo Leal | Carrege o arquivo: |
| 97 | 23 | Beraldo Leal | |
| 98 | 23 | Beraldo Leal | <pre> |
| 99 | 23 | Beraldo Leal | # source /root/openstackrc |
| 100 | 23 | Beraldo Leal | </pre> |
| 101 | 24 | Beraldo Leal | |
| 102 | 26 | Beraldo Leal | Crie os *tenants* _openstackDemo_ e _service_: |
| 103 | 24 | Beraldo Leal | |
| 104 | 24 | Beraldo Leal | <pre> |
| 105 | 24 | Beraldo Leal | # keystone tenant-create --name openstackDemo --description "Default Tenant" --enabled true |
| 106 | 24 | Beraldo Leal | # keystone tenant-create --name service --description "Service Tenant" --enabled true |
| 107 | 24 | Beraldo Leal | </pre> |
| 108 | 25 | Beraldo Leal | |
| 109 | 27 | Beraldo Leal | Crie o *user* _admin_, substitua o tenant_id pelo tentant_id do openstackDemo, criado no item anterior: |
| 110 | 25 | Beraldo Leal | |
| 111 | 1 | Beraldo Leal | <pre> |
| 112 | 1 | Beraldo Leal | # keystone user-create --tenant_id 9c401c9d2b9d41bcabda6919d4aec63a --name admin --pass adminpass --enabled true |
| 113 | 26 | Beraldo Leal | </pre> |
| 114 | 26 | Beraldo Leal | |
| 115 | 26 | Beraldo Leal | Crie os *roles* _admin_ e _user_: |
| 116 | 26 | Beraldo Leal | |
| 117 | 26 | Beraldo Leal | <pre> |
| 118 | 26 | Beraldo Leal | # keystone role-create --name admin |
| 119 | 1 | Beraldo Leal | # keystone role-create --name user |
| 120 | 27 | Beraldo Leal | </pre> |
| 121 | 27 | Beraldo Leal | |
| 122 | 27 | Beraldo Leal | Adicione o *user* _admin_ ao *role* _admin_, fazendo as devidas substituicoes: |
| 123 | 27 | Beraldo Leal | |
| 124 | 27 | Beraldo Leal | <pre> |
| 125 | 29 | Beraldo Leal | # keystone user-role-add --user [admin_user_id] --tenant_id [openstackDemo_tenant_id] --role [admin_role] |
| 126 | 29 | Beraldo Leal | </pre> |
| 127 | 29 | Beraldo Leal | |
| 128 | 29 | Beraldo Leal | Crie um usuario para cada servico, e substitua o tenant_id pelo id do tenant *service*: |
| 129 | 29 | Beraldo Leal | |
| 130 | 29 | Beraldo Leal | <pre> |
| 131 | 29 | Beraldo Leal | # keystone user-create --tenant_id 92920816c7704a8a95c916d34dc7a05c --name glance --pass glancepass --enabled true |
| 132 | 29 | Beraldo Leal | # keystone user-create --tenant_id 92920816c7704a8a95c916d34dc7a05c --name nova --pass novapass --enabled true |
| 133 | 29 | Beraldo Leal | # keystone user-create --tenant_id 92920816c7704a8a95c916d34dc7a05c --name swift --pass swiftpass --enabled true |
| 134 | 29 | Beraldo Leal | </pre> |
| 135 | 29 | Beraldo Leal | |
| 136 | 29 | Beraldo Leal | Adicione os users acima ao *role* _admin_, fazendo as devidas substituicoes: |
| 137 | 29 | Beraldo Leal | |
| 138 | 29 | Beraldo Leal | <pre> |
| 139 | 29 | Beraldo Leal | # keystone user-role-add --user [glance_user_id] --tenant_id [service_tenant_id] --role [admin_role] |
| 140 | 1 | Beraldo Leal | # keystone user-role-add --user [nova_user_id] --tenant_id [service_tenant_id] --role [admin_role] |
| 141 | 29 | Beraldo Leal | # keystone user-role-add --user [swift_user_id] --tenant_id [service_tenant_id] --role [admin_role] |
| 142 | 25 | Beraldo Leal | </pre> |
| 143 | 31 | Beraldo Leal | |
| 144 | 37 | Beraldo Leal | h2. Definindo os servicos: |
| 145 | 31 | Beraldo Leal | |
| 146 | 31 | Beraldo Leal | Ate agora, apenas criamos: tenants, users e roles. O Keystone tambem gerencia os servicos e seus endpoins. Desta forma os componentes do openstack consulta o keystone onde determinado servico encontra-se. |
| 147 | 31 | Beraldo Leal | |
| 148 | 31 | Beraldo Leal | Crie os servicos: |
| 149 | 31 | Beraldo Leal | |
| 150 | 31 | Beraldo Leal | <pre> |
| 151 | 31 | Beraldo Leal | # keystone service-create --name keystone --type identity --description "Keystone Identity Service" |
| 152 | 31 | Beraldo Leal | # keystone service-create --name nova --type compute --description "Nova Compute Service" |
| 153 | 31 | Beraldo Leal | # keystone service-create --name volume --type volume --description "Nova Volume Service" |
| 154 | 31 | Beraldo Leal | # keystone service-create --name glance --type image --description "Glance Image Service" |
| 155 | 41 | Beraldo Leal | # keystone service-create --name swift --type object-store --description "Object Storage Service" |
| 156 | 31 | Beraldo Leal | </pre> |
| 157 | 32 | Beraldo Leal | |
| 158 | 32 | Beraldo Leal | Crie os endpoints para os respectivos servicos: |
| 159 | 32 | Beraldo Leal | |
| 160 | 32 | Beraldo Leal | <pre> |
| 161 | 33 | Beraldo Leal | # keystone endpoint-create --region RegionOne --service_id [keystone_service_id] --publicurl http://192.168.69.1:5000/v2.0 --internalurl http://192.168.69.1:5000/v2.0 --adminurl http://192.168.69.1:35357/v2.0 |
| 162 | 33 | Beraldo Leal | # keystone endpoint-create --region RegionOne --service_id [compute_service_id] --publicurl 'http://192.168.69.1:8774/v2/%(tenant_id)s' --internalurl 'http://192.168.69.1:8774/v2/%(tenant_id)s' --adminurl 'http://192.168.69.1:8774/v2/%(tenant_id)s' |
| 163 | 1 | Beraldo Leal | # keystone endpoint-create --region RegionOne --service_id [volume_service_id] --publicurl 'http://192.168.69.1:8776/v1/%(tenant_id)s' --internalurl 'http://192.168.69.1:8776/v1/%(tenant_id)s' --adminurl 'http://192.168.69.1:8776/v1/%(tenant_id)s' |
| 164 | 33 | Beraldo Leal | # keystone endpoint-create --region RegionOne --service_id [glance_service_id] --publicurl http://192.168.69.1:9292/v1 --internalurl http://192.168.69.1:9292/v1 --adminurl http://192.168.69.1:9292/v1 |
| 165 | 33 | Beraldo Leal | # keystone endpoint-create --region RegionOne --service_id [swift_service_id] --publicurl 'http://192.168.69.1:8888/v1/AUTH_%(tenant_id)s' --adminurl 'http://192.168.69.1:8888/' --internalurl 'http://192.168.69.1:8888/v1/AUTH_%(tenant_id)s' |
| 166 | 32 | Beraldo Leal | </pre> |
| 167 | 34 | Beraldo Leal | |
| 168 | 37 | Beraldo Leal | h2. Verificando a instalacao: |
| 169 | 34 | Beraldo Leal | |
| 170 | 34 | Beraldo Leal | <pre> |
| 171 | 34 | Beraldo Leal | # sudo apt-get install curl openssl |
| 172 | 34 | Beraldo Leal | </pre> |
| 173 | 34 | Beraldo Leal | |
| 174 | 34 | Beraldo Leal | Faca uma requisicao REST para a API do keystone usando o curl: |
| 175 | 34 | Beraldo Leal | |
| 176 | 34 | Beraldo Leal | <pre> |
| 177 | 34 | Beraldo Leal | # curl -d '{"auth": {"tenantName": "openstackDemo", "passwordCredentials": {"username": "admin", "password": "adminpass"}}}' -H "Content-type: application/json" http://192.168.69.1:35357/v2.0/tokens | python -mjson.tool |
| 178 | 34 | Beraldo Leal | </pre> |
| 179 | 34 | Beraldo Leal | |
| 180 | 35 | Beraldo Leal | O retorno deve conter todos os servicos, endpoins e um token que expira em 24 horas: |
| 181 | 34 | Beraldo Leal | |
| 182 | 34 | Beraldo Leal | <pre> |
| 183 | 34 | Beraldo Leal | { |
| 184 | 34 | Beraldo Leal | "access": { |
| 185 | 34 | Beraldo Leal | "serviceCatalog": [ |
| 186 | 34 | Beraldo Leal | { |
| 187 | 34 | Beraldo Leal | "endpoints": [ |
| 188 | 34 | Beraldo Leal | { |
| 189 | 34 | Beraldo Leal | "adminURL": "http://192.168.69.1:8776/v1/9c401c9d2b9d41bcabda6919d4aec63a", |
| 190 | 34 | Beraldo Leal | "internalURL": "http://192.168.69.1:8776/v1/9c401c9d2b9d41bcabda6919d4aec63a", |
| 191 | 34 | Beraldo Leal | "publicURL": "http://192.168.69.1:8776/v1/9c401c9d2b9d41bcabda6919d4aec63a", |
| 192 | 34 | Beraldo Leal | "region": "RegionOne" |
| 193 | 34 | Beraldo Leal | } |
| 194 | 34 | Beraldo Leal | ], |
| 195 | 34 | Beraldo Leal | "endpoints_links": [], |
| 196 | 34 | Beraldo Leal | "name": "volume", |
| 197 | 34 | Beraldo Leal | "type": "volume" |
| 198 | 34 | Beraldo Leal | }, |
| 199 | 34 | Beraldo Leal | { |
| 200 | 34 | Beraldo Leal | "endpoints": [ |
| 201 | 34 | Beraldo Leal | { |
| 202 | 34 | Beraldo Leal | "adminURL": "http://192.168.69.1:9292/v1", |
| 203 | 34 | Beraldo Leal | "internalURL": "http://192.168.69.1:9292/v1", |
| 204 | 34 | Beraldo Leal | "publicURL": "http://192.168.69.1:9292/v1", |
| 205 | 34 | Beraldo Leal | "region": "RegionOne" |
| 206 | 34 | Beraldo Leal | } |
| 207 | 34 | Beraldo Leal | ], |
| 208 | 34 | Beraldo Leal | "endpoints_links": [], |
| 209 | 34 | Beraldo Leal | "name": "glance", |
| 210 | 34 | Beraldo Leal | "type": "image" |
| 211 | 34 | Beraldo Leal | }, |
| 212 | 34 | Beraldo Leal | { |
| 213 | 34 | Beraldo Leal | "endpoints": [ |
| 214 | 34 | Beraldo Leal | { |
| 215 | 34 | Beraldo Leal | "adminURL": "http://192.168.69.1:8774/v2/9c401c9d2b9d41bcabda6919d4aec63a", |
| 216 | 34 | Beraldo Leal | "internalURL": "http://192.168.69.1:8774/v2/9c401c9d2b9d41bcabda6919d4aec63a", |
| 217 | 34 | Beraldo Leal | "publicURL": "http://192.168.69.1:8774/v2/9c401c9d2b9d41bcabda6919d4aec63a", |
| 218 | 34 | Beraldo Leal | "region": "RegionOne" |
| 219 | 34 | Beraldo Leal | } |
| 220 | 34 | Beraldo Leal | ], |
| 221 | 34 | Beraldo Leal | "endpoints_links": [], |
| 222 | 34 | Beraldo Leal | "name": "nova", |
| 223 | 34 | Beraldo Leal | "type": "compute" |
| 224 | 34 | Beraldo Leal | }, |
| 225 | 34 | Beraldo Leal | { |
| 226 | 34 | Beraldo Leal | "endpoints": [ |
| 227 | 34 | Beraldo Leal | { |
| 228 | 34 | Beraldo Leal | "adminURL": "http://192.168.69.1:35357/v2.0", |
| 229 | 34 | Beraldo Leal | "internalURL": "http://192.168.69.1:5000/v2.0", |
| 230 | 34 | Beraldo Leal | "publicURL": "http://192.168.69.1:5000/v2.0", |
| 231 | 34 | Beraldo Leal | "region": "RegionOne" |
| 232 | 34 | Beraldo Leal | } |
| 233 | 34 | Beraldo Leal | ], |
| 234 | 34 | Beraldo Leal | "endpoints_links": [], |
| 235 | 34 | Beraldo Leal | "name": "keystone", |
| 236 | 34 | Beraldo Leal | "type": "identity" |
| 237 | 34 | Beraldo Leal | }, |
| 238 | 34 | Beraldo Leal | { |
| 239 | 34 | Beraldo Leal | "endpoints": [ |
| 240 | 34 | Beraldo Leal | { |
| 241 | 34 | Beraldo Leal | "adminURL": "http://192.168.69.1:8888/", |
| 242 | 34 | Beraldo Leal | "internalURL": "http://192.168.69.1:8888/v1/AUTH_9c401c9d2b9d41bcabda6919d4aec63a", |
| 243 | 34 | Beraldo Leal | "publicURL": "http://192.168.69.1:8888/v1/AUTH_9c401c9d2b9d41bcabda6919d4aec63a", |
| 244 | 34 | Beraldo Leal | "region": "RegionOne" |
| 245 | 34 | Beraldo Leal | } |
| 246 | 34 | Beraldo Leal | ], |
| 247 | 34 | Beraldo Leal | "endpoints_links": [], |
| 248 | 34 | Beraldo Leal | "name": "swift", |
| 249 | 41 | Beraldo Leal | "type": "object-store" |
| 250 | 34 | Beraldo Leal | } |
| 251 | 34 | Beraldo Leal | ], |
| 252 | 34 | Beraldo Leal | "token": { |
| 253 | 34 | Beraldo Leal | "expires": "2012-06-08T15:31:46Z", |
| 254 | 34 | Beraldo Leal | "id": "05b818ff23564d5599c97ea5e1df7bbe", |
| 255 | 34 | Beraldo Leal | "tenant": { |
| 256 | 34 | Beraldo Leal | "description": "Default Tenant", |
| 257 | 34 | Beraldo Leal | "enabled": true, |
| 258 | 34 | Beraldo Leal | "id": "9c401c9d2b9d41bcabda6919d4aec63a", |
| 259 | 34 | Beraldo Leal | "name": "openstackDemo" |
| 260 | 34 | Beraldo Leal | } |
| 261 | 34 | Beraldo Leal | }, |
| 262 | 34 | Beraldo Leal | "user": { |
| 263 | 34 | Beraldo Leal | "id": "1fcfbe778fc3428aa30db782056b34d7", |
| 264 | 34 | Beraldo Leal | "name": "admin", |
| 265 | 34 | Beraldo Leal | "roles": [ |
| 266 | 34 | Beraldo Leal | { |
| 267 | 34 | Beraldo Leal | "id": "a2d6da77c0a54105aab94484e0d2088b", |
| 268 | 34 | Beraldo Leal | "name": "admin" |
| 269 | 34 | Beraldo Leal | } |
| 270 | 34 | Beraldo Leal | ], |
| 271 | 34 | Beraldo Leal | "roles_links": [], |
| 272 | 34 | Beraldo Leal | "username": "admin" |
| 273 | 34 | Beraldo Leal | } |
| 274 | 34 | Beraldo Leal | } |
| 275 | 34 | Beraldo Leal | } |
| 276 | 34 | Beraldo Leal | |
| 277 | 34 | Beraldo Leal | </pre> |
| 278 | 36 | Beraldo Leal | |
| 279 | 36 | Beraldo Leal | Voce pode tambem listar usuarios, roles, tenants e services: |
| 280 | 36 | Beraldo Leal | |
| 281 | 36 | Beraldo Leal | <pre> |
| 282 | 36 | Beraldo Leal | # keystone user-list |
| 283 | 39 | Beraldo Leal | +----------------------------------+---------+-------+--------+ |
| 284 | 39 | Beraldo Leal | | id | enabled | email | name | |
| 285 | 39 | Beraldo Leal | +----------------------------------+---------+-------+--------+ |
| 286 | 39 | Beraldo Leal | | 029c5749548946f7b560b2706d31d488 | True | None | glance | |
| 287 | 39 | Beraldo Leal | | 1fcfbe778fc3428aa30db782056b34d7 | True | None | admin | |
| 288 | 39 | Beraldo Leal | | 4b75079aeb1b408ebdb286bfb85e719f | True | None | swift | |
| 289 | 39 | Beraldo Leal | | e25f81d50eb84bdb92907adbd0e41f25 | True | None | nova | |
| 290 | 39 | Beraldo Leal | +----------------------------------+---------+-------+--------+ |
| 291 | 40 | Beraldo Leal | </pre> |
| 292 | 39 | Beraldo Leal | |
| 293 | 40 | Beraldo Leal | <pre> |
| 294 | 36 | Beraldo Leal | # keystone role-list |
| 295 | 39 | Beraldo Leal | +----------------------------------+-------+ |
| 296 | 39 | Beraldo Leal | | id | name | |
| 297 | 39 | Beraldo Leal | +----------------------------------+-------+ |
| 298 | 39 | Beraldo Leal | | 845e83e4d9bf4d8d8188b1e261dfe103 | user | |
| 299 | 39 | Beraldo Leal | | a2d6da77c0a54105aab94484e0d2088b | admin | |
| 300 | 39 | Beraldo Leal | +----------------------------------+-------+ |
| 301 | 40 | Beraldo Leal | </pre> |
| 302 | 1 | Beraldo Leal | |
| 303 | 40 | Beraldo Leal | <pre> |
| 304 | 36 | Beraldo Leal | # keystone tenant-list |
| 305 | 39 | Beraldo Leal | +----------------------------------+---------------+---------+ |
| 306 | 39 | Beraldo Leal | | id | name | enabled | |
| 307 | 39 | Beraldo Leal | +----------------------------------+---------------+---------+ |
| 308 | 39 | Beraldo Leal | | 92920816c7704a8a95c916d34dc7a05c | service | True | |
| 309 | 39 | Beraldo Leal | | 9c401c9d2b9d41bcabda6919d4aec63a | openstackDemo | True | |
| 310 | 1 | Beraldo Leal | +----------------------------------+---------------+---------+ |
| 311 | 40 | Beraldo Leal | </pre> |
| 312 | 1 | Beraldo Leal | |
| 313 | 40 | Beraldo Leal | <pre> |
| 314 | 36 | Beraldo Leal | # keystone service-list |
| 315 | 39 | Beraldo Leal | +----------------------------------+----------+----------------+---------------------------+ |
| 316 | 39 | Beraldo Leal | | id | name | type | description | |
| 317 | 39 | Beraldo Leal | +----------------------------------+----------+----------------+---------------------------+ |
| 318 | 39 | Beraldo Leal | | 00486163c7c64c6a86f577627071aafc | nova | compute | Nova Compute Service | |
| 319 | 39 | Beraldo Leal | | 69d3a6b21c9348acb1042d7d9386ff81 | volume | volume | Nova Volume Service | |
| 320 | 41 | Beraldo Leal | | 7b09782f9faf448781f5a460acabe258 | swift | object-store | Object Storage Service | |
| 321 | 39 | Beraldo Leal | | d6b32583a6694e9b828b2a50037623ba | keystone | identity | Keystone Identity Service | |
| 322 | 39 | Beraldo Leal | | f7f964a71e2a45119dcaede68fafbd78 | glance | image | Glance Image Service | |
| 323 | 39 | Beraldo Leal | +----------------------------------+----------+----------------+---------------------------+ |
| 324 | 36 | Beraldo Leal | </pre> |
| 325 | 38 | Beraldo Leal | |
| 326 | 38 | Beraldo Leal | h1. Installing OpenStack Object Storage - Swift |
| 327 | 42 | Beraldo Leal | |
| 328 | 1 | Beraldo Leal | [Descrever o Swift aqui] |
| 329 | 44 | Beraldo Leal | |
| 330 | 44 | Beraldo Leal | Como neste ambiente de desenvolvimento temos apenas um no para storage e este sera o mesmo no que estara instalado o swift-proxy, todos os passos abaixo, sao executados na mesma maquina: _educloud01_. |
| 331 | 44 | Beraldo Leal | |
| 332 | 44 | Beraldo Leal | Em um ambiente de producao aconselha-se ter pelo menos 05 object storage nodes e 01 object proxy node. |
| 333 | 44 | Beraldo Leal | |
| 334 | 44 | Beraldo Leal | h2. Instalando e configurando o swift |
| 335 | 44 | Beraldo Leal | |
| 336 | 44 | Beraldo Leal | <pre> |
| 337 | 44 | Beraldo Leal | # apt-get install swift python-xattr python-memcache rsync memcached python-netifaces |
| 338 | 44 | Beraldo Leal | </pre> |
| 339 | 44 | Beraldo Leal | |
| 340 | 44 | Beraldo Leal | Infelizmente no momento da escrita deste manual o pacote do swift nao automatiza algumas tarefas, como por exemplo, a criacao dos arquivos de configuracao. Teremos que fazer isso manualmente: |
| 341 | 44 | Beraldo Leal | |
| 342 | 44 | Beraldo Leal | <pre> |
| 343 | 44 | Beraldo Leal | # mkdir /etc/swift |
| 344 | 44 | Beraldo Leal | </pre> |
| 345 | 44 | Beraldo Leal | |
| 346 | 44 | Beraldo Leal | Crie o arquivo de configuracao _/etc/swift/swift.conf_: |
| 347 | 44 | Beraldo Leal | |
| 348 | 44 | Beraldo Leal | <pre> |
| 349 | 44 | Beraldo Leal | [swift-hash] |
| 350 | 44 | Beraldo Leal | # random unique string that can never change (DO NOT LOSE) |
| 351 | 44 | Beraldo Leal | swift_hash_path_suffix = fLIbertYgibbitZ |
| 352 | 44 | Beraldo Leal | </pre> |
| 353 | 44 | Beraldo Leal | |
| 354 | 44 | Beraldo Leal | h2. Instalando e configurando os "object nodes" |
| 355 | 44 | Beraldo Leal | |
| 356 | 44 | Beraldo Leal | <pre> |
| 357 | 44 | Beraldo Leal | # apt-get install swift-account swift-container swift-object xfsprogs |
| 358 | 44 | Beraldo Leal | </pre> |
| 359 | 44 | Beraldo Leal | |
| 360 | 44 | Beraldo Leal | Cada "Object node" pode ter muitos dispositivos ligados a eles. 'E necessario que seja utilizado o sistema de arquivos xfs. |
| 361 | 44 | Beraldo Leal | |
| 362 | 44 | Beraldo Leal | <pre> |
| 363 | 44 | Beraldo Leal | # fdisk /dev/sdb (set up a single partition) |
| 364 | 44 | Beraldo Leal | # mkfs.xfs -i size=1024 /dev/sdb1 |
| 365 | 44 | Beraldo Leal | </pre> |
| 366 | 44 | Beraldo Leal | |
| 367 | 44 | Beraldo Leal | |
| 368 | 44 | Beraldo Leal | Este dispositivo deve estar montando em /srv/node/ |
| 369 | 44 | Beraldo Leal | |
| 370 | 44 | Beraldo Leal | <pre> |
| 371 | 44 | Beraldo Leal | echo "/dev/sdb1 /srv/node/sdb1 xfs noatime,nodiratime,nobarrier,logbufs=8 0 0" >> /etc/fstab |
| 372 | 44 | Beraldo Leal | mkdir -p /srv/node/sdb1 |
| 373 | 44 | Beraldo Leal | mount /srv/node/sdb1 |
| 374 | 44 | Beraldo Leal | chown -R swift:swift /srv/node |
| 375 | 44 | Beraldo Leal | </pre> |
| 376 | 44 | Beraldo Leal | |
| 377 | 44 | Beraldo Leal | h2. Configure o _rsyncd.conf_ |
| 378 | 44 | Beraldo Leal | |
| 379 | 44 | Beraldo Leal | <pre> |
| 380 | 44 | Beraldo Leal | uid = swift |
| 381 | 44 | Beraldo Leal | gid = swift |
| 382 | 44 | Beraldo Leal | log file = /var/log/rsyncd.log |
| 383 | 44 | Beraldo Leal | pid file = /var/run/rsyncd.pid |
| 384 | 44 | Beraldo Leal | address = 192.168.69.1 |
| 385 | 44 | Beraldo Leal | |
| 386 | 44 | Beraldo Leal | [account] |
| 387 | 44 | Beraldo Leal | max connections = 2 |
| 388 | 44 | Beraldo Leal | path = /srv/node/ |
| 389 | 44 | Beraldo Leal | read only = false |
| 390 | 44 | Beraldo Leal | lock file = /var/lock/account.lock |
| 391 | 44 | Beraldo Leal | |
| 392 | 44 | Beraldo Leal | [container] |
| 393 | 44 | Beraldo Leal | max connections = 2 |
| 394 | 44 | Beraldo Leal | path = /srv/node/ |
| 395 | 44 | Beraldo Leal | read only = false |
| 396 | 44 | Beraldo Leal | lock file = /var/lock/container.lock |
| 397 | 44 | Beraldo Leal | |
| 398 | 44 | Beraldo Leal | [object] |
| 399 | 44 | Beraldo Leal | max connections = 2 |
| 400 | 44 | Beraldo Leal | path = /srv/node/ |
| 401 | 44 | Beraldo Leal | read only = false |
| 402 | 44 | Beraldo Leal | lock file = /var/lock/object.lock |
| 403 | 44 | Beraldo Leal | </pre> |
| 404 | 44 | Beraldo Leal | |
| 405 | 44 | Beraldo Leal | Edite o _/etc/default/rsync_: |
| 406 | 44 | Beraldo Leal | |
| 407 | 44 | Beraldo Leal | <pre> |
| 408 | 44 | Beraldo Leal | RSYNC_ENABLE = true |
| 409 | 44 | Beraldo Leal | </pre> |
| 410 | 44 | Beraldo Leal | |
| 411 | 44 | Beraldo Leal | Restarte o rsync: |
| 412 | 44 | Beraldo Leal | |
| 413 | 44 | Beraldo Leal | <pre> |
| 414 | 44 | Beraldo Leal | service rsync restart |
| 415 | 44 | Beraldo Leal | </pre> |
| 416 | 44 | Beraldo Leal | |
| 417 | 44 | Beraldo Leal | Crie o _/etc/swift/account-server.conf_: |
| 418 | 44 | Beraldo Leal | |
| 419 | 44 | Beraldo Leal | <pre> |
| 420 | 44 | Beraldo Leal | [DEFAULT] |
| 421 | 44 | Beraldo Leal | bind_ip = 192.168.69.1 |
| 422 | 44 | Beraldo Leal | workers = 2 |
| 423 | 44 | Beraldo Leal | |
| 424 | 44 | Beraldo Leal | [pipeline:main] |
| 425 | 44 | Beraldo Leal | pipeline = account-server |
| 426 | 44 | Beraldo Leal | |
| 427 | 44 | Beraldo Leal | [app:account-server] |
| 428 | 44 | Beraldo Leal | use = egg:swift#account |
| 429 | 44 | Beraldo Leal | |
| 430 | 44 | Beraldo Leal | [account-replicator] |
| 431 | 44 | Beraldo Leal | |
| 432 | 44 | Beraldo Leal | [account-auditor] |
| 433 | 44 | Beraldo Leal | |
| 434 | 44 | Beraldo Leal | [account-reaper] |
| 435 | 44 | Beraldo Leal | </pre> |
| 436 | 44 | Beraldo Leal | |
| 437 | 44 | Beraldo Leal | Crie o _/etc/swift/container-server.conf_: |
| 438 | 44 | Beraldo Leal | |
| 439 | 44 | Beraldo Leal | <pre> |
| 440 | 44 | Beraldo Leal | [DEFAULT] |
| 441 | 44 | Beraldo Leal | bind_ip = 192.168.69.1 |
| 442 | 44 | Beraldo Leal | workers = 2 |
| 443 | 44 | Beraldo Leal | |
| 444 | 44 | Beraldo Leal | [pipeline:main] |
| 445 | 44 | Beraldo Leal | pipeline = container-server |
| 446 | 44 | Beraldo Leal | |
| 447 | 44 | Beraldo Leal | [app:container-server] |
| 448 | 44 | Beraldo Leal | use = egg:swift#container |
| 449 | 44 | Beraldo Leal | |
| 450 | 44 | Beraldo Leal | [container-replicator] |
| 451 | 44 | Beraldo Leal | |
| 452 | 44 | Beraldo Leal | [container-updater] |
| 453 | 44 | Beraldo Leal | |
| 454 | 44 | Beraldo Leal | [container-auditor] |
| 455 | 44 | Beraldo Leal | </pre> |
| 456 | 44 | Beraldo Leal | |
| 457 | 44 | Beraldo Leal | Crie o _/etc/swift/object-server.conf_: |
| 458 | 44 | Beraldo Leal | |
| 459 | 44 | Beraldo Leal | <pre> |
| 460 | 44 | Beraldo Leal | [DEFAULT] |
| 461 | 44 | Beraldo Leal | bind_ip = 192.168.69.1 |
| 462 | 44 | Beraldo Leal | workers = 2 |
| 463 | 44 | Beraldo Leal | |
| 464 | 44 | Beraldo Leal | [pipeline:main] |
| 465 | 44 | Beraldo Leal | pipeline = object-server |
| 466 | 44 | Beraldo Leal | |
| 467 | 44 | Beraldo Leal | [app:object-server] |
| 468 | 44 | Beraldo Leal | use = egg:swift#object |
| 469 | 44 | Beraldo Leal | |
| 470 | 44 | Beraldo Leal | [object-replicator] |
| 471 | 44 | Beraldo Leal | |
| 472 | 44 | Beraldo Leal | [object-updater] |
| 473 | 44 | Beraldo Leal | |
| 474 | 44 | Beraldo Leal | [object-auditor] |
| 475 | 44 | Beraldo Leal | </pre> |
| 476 | 44 | Beraldo Leal | |
| 477 | 44 | Beraldo Leal | |
| 478 | 44 | Beraldo Leal | h2. Instale e configure o swift-proxy |
| 479 | 44 | Beraldo Leal | |
| 480 | 44 | Beraldo Leal | <pre> |
| 481 | 44 | Beraldo Leal | # apt-get install swift-proxy memcached |
| 482 | 44 | Beraldo Leal | </pre> |
| 483 | 44 | Beraldo Leal | |
| 484 | 44 | Beraldo Leal | Crie o certificado SSL auto assinado: |
| 485 | 44 | Beraldo Leal | |
| 486 | 44 | Beraldo Leal | <pre> |
| 487 | 44 | Beraldo Leal | cd /etc/swift |
| 488 | 44 | Beraldo Leal | openssl req -new -x509 -nodes -out cert.crt -keyout cert.key |
| 489 | 44 | Beraldo Leal | </pre> |
| 490 | 44 | Beraldo Leal | |
| 491 | 44 | Beraldo Leal | Modifique o memcached para ouvir na interface da sua rede interna. Edite a seguinte linha no /etc/memcached.conf, mudando |
| 492 | 44 | Beraldo Leal | |
| 493 | 44 | Beraldo Leal | <pre> |
| 494 | 44 | Beraldo Leal | -l 127.0.0.1 |
| 495 | 44 | Beraldo Leal | to |
| 496 | 44 | Beraldo Leal | -l 192.168.69.1 |
| 497 | 44 | Beraldo Leal | </pre> |
| 498 | 44 | Beraldo Leal | |
| 499 | 44 | Beraldo Leal | Restart o memcached: |
| 500 | 44 | Beraldo Leal | |
| 501 | 44 | Beraldo Leal | <pre> |
| 502 | 44 | Beraldo Leal | service memcached restart |
| 503 | 44 | Beraldo Leal | </pre> |
| 504 | 44 | Beraldo Leal | |
| 505 | 44 | Beraldo Leal | Crie o arquivo _/etc/swift/proxy-server.conf_: |
| 506 | 44 | Beraldo Leal | |
| 507 | 44 | Beraldo Leal | <pre> |
| 508 | 44 | Beraldo Leal | [DEFAULT] |
| 509 | 44 | Beraldo Leal | bind_port = 8888 |
| 510 | 44 | Beraldo Leal | user = swift |
| 511 | 44 | Beraldo Leal | |
| 512 | 44 | Beraldo Leal | [pipeline:main] |
| 513 | 44 | Beraldo Leal | pipeline = catch_errors healthcheck cache authtoken keystone proxy-server |
| 514 | 44 | Beraldo Leal | |
| 515 | 44 | Beraldo Leal | [app:proxy-server] |
| 516 | 44 | Beraldo Leal | use = egg:swift#proxy |
| 517 | 44 | Beraldo Leal | account_autocreate = true |
| 518 | 44 | Beraldo Leal | |
| 519 | 44 | Beraldo Leal | [filter:keystone] |
| 520 | 44 | Beraldo Leal | paste.filter_factory = keystone.middleware.swift_auth:filter_factory |
| 521 | 44 | Beraldo Leal | operator_roles = admin, swiftoperator |
| 522 | 44 | Beraldo Leal | |
| 523 | 44 | Beraldo Leal | [filter:authtoken] |
| 524 | 44 | Beraldo Leal | paste.filter_factory = keystone.middleware.auth_token:filter_factory |
| 525 | 44 | Beraldo Leal | # Delaying the auth decision is required to support token-less |
| 526 | 44 | Beraldo Leal | # usage for anonymous referrers ('.r:*'). |
| 527 | 44 | Beraldo Leal | delay_auth_decision = 10 |
| 528 | 44 | Beraldo Leal | service_port = 5000 |
| 529 | 44 | Beraldo Leal | service_host = 192.168.69.1 |
| 530 | 44 | Beraldo Leal | auth_port = 35357 |
| 531 | 44 | Beraldo Leal | auth_host = 192.168.69.1 |
| 532 | 44 | Beraldo Leal | auth_token = 012345SECRET99TOKEN012345 |
| 533 | 44 | Beraldo Leal | admin_token = 012345SECRET99TOKEN012345 |
| 534 | 44 | Beraldo Leal | auth_protocol = http |
| 535 | 44 | Beraldo Leal | |
| 536 | 44 | Beraldo Leal | [filter:cache] |
| 537 | 44 | Beraldo Leal | use = egg:swift#memcache |
| 538 | 44 | Beraldo Leal | set log_name = cache |
| 539 | 44 | Beraldo Leal | |
| 540 | 44 | Beraldo Leal | [filter:catch_errors] |
| 541 | 44 | Beraldo Leal | use = egg:swift#catch_errors |
| 542 | 44 | Beraldo Leal | |
| 543 | 44 | Beraldo Leal | [filter:healthcheck] |
| 544 | 44 | Beraldo Leal | use = egg:swift#healthcheck |
| 545 | 44 | Beraldo Leal | </pre> |
| 546 | 44 | Beraldo Leal | |
| 547 | 45 | Beraldo Leal | |
| 548 | 45 | Beraldo Leal | Create the account, container and object rings. The builder command is basically creating a builder file with a few parameters. The parameter with the value of 18 represents 2 ^ 18th, the value that the partition will be sized to. Set this "partition power" value based on the total amount of storage you expect your entire ring to use. The value of 1 represents the number of replicas of each object, with the last value being the number of hours to restrict moving a partition more than once. |
| 549 | 45 | Beraldo Leal | |
| 550 | 45 | Beraldo Leal | <pre> |
| 551 | 45 | Beraldo Leal | cd /etc/swift |
| 552 | 45 | Beraldo Leal | swift-ring-builder account.builder create 18 1 1 |
| 553 | 45 | Beraldo Leal | swift-ring-builder container.builder create 18 1 1 |
| 554 | 45 | Beraldo Leal | swift-ring-builder object.builder create 18 1 1 |
| 555 | 45 | Beraldo Leal | </pre> |
| 556 | 45 | Beraldo Leal | |
| 557 | 45 | Beraldo Leal | For every storage device on each node add entries to each ring: |
| 558 | 45 | Beraldo Leal | |
| 559 | 45 | Beraldo Leal | <pre> |
| 560 | 45 | Beraldo Leal | swift-ring-builder account.builder add z<ZONE>-<STORAGE_LOCAL_NET_IP>:6002/<DEVICE> 100 |
| 561 | 45 | Beraldo Leal | swift-ring-builder container.builder add z<ZONE>-<STORAGE_LOCAL_NET_IP_1>:6001/<DEVICE> 100 |
| 562 | 45 | Beraldo Leal | swift-ring-builder object.builder add z<ZONE>-<STORAGE_LOCAL_NET_IP_1>:6000/<DEVICE> 100 |
| 563 | 45 | Beraldo Leal | </pre> |
| 564 | 45 | Beraldo Leal | |
| 565 | 45 | Beraldo Leal | Como no nosso caso, apenas temos uma zona, em um storage node e com um device (sdb1), o comando acima ficaria: |
| 566 | 45 | Beraldo Leal | |
| 567 | 45 | Beraldo Leal | <pre> |
| 568 | 45 | Beraldo Leal | swift-ring-builder account.builder add z1-192.168.69.1:6002/sdb1 100 |
| 569 | 45 | Beraldo Leal | swift-ring-builder container.builder add z1-192.168.69.1:6001/sdb1 100 |
| 570 | 45 | Beraldo Leal | swift-ring-builder object.builder add z1-192.168.69.1:6000/sdb1 100 |
| 571 | 45 | Beraldo Leal | </pre> |
| 572 | 45 | Beraldo Leal | |
| 573 | 45 | Beraldo Leal | Verify the ring contents for each ring: |
| 574 | 45 | Beraldo Leal | |
| 575 | 45 | Beraldo Leal | <pre> |
| 576 | 45 | Beraldo Leal | swift-ring-builder account.builder |
| 577 | 45 | Beraldo Leal | swift-ring-builder container.builder |
| 578 | 45 | Beraldo Leal | swift-ring-builder object.builder |
| 579 | 45 | Beraldo Leal | </pre> |
| 580 | 45 | Beraldo Leal | |
| 581 | 45 | Beraldo Leal | Rebalance the rings: |
| 582 | 45 | Beraldo Leal | |
| 583 | 45 | Beraldo Leal | <pre> |
| 584 | 45 | Beraldo Leal | swift-ring-builder account.builder rebalance |
| 585 | 45 | Beraldo Leal | swift-ring-builder container.builder rebalance |
| 586 | 45 | Beraldo Leal | swift-ring-builder object.builder rebalance |
| 587 | 45 | Beraldo Leal | </pre> |
| 588 | 45 | Beraldo Leal | |
| 589 | 44 | Beraldo Leal | Altere as permissoes dos arquivos de configuracao: |
| 590 | 44 | Beraldo Leal | |
| 591 | 44 | Beraldo Leal | <pre> |
| 592 | 44 | Beraldo Leal | # chown -R swift:swift /etc/swift/ |
| 593 | 44 | Beraldo Leal | </pre> |
| 594 | 45 | Beraldo Leal | |
| 595 | 45 | Beraldo Leal | Inicie o swift-proxy: |
| 596 | 45 | Beraldo Leal | |
| 597 | 45 | Beraldo Leal | <pre> |
| 598 | 45 | Beraldo Leal | swift-init proxy start |
| 599 | 45 | Beraldo Leal | </pre> |
| 600 | 45 | Beraldo Leal | |
| 601 | 45 | Beraldo Leal | Inicie todos os servicos: |
| 602 | 45 | Beraldo Leal | |
| 603 | 45 | Beraldo Leal | <pre> |
| 604 | 45 | Beraldo Leal | swift-init main start |
| 605 | 45 | Beraldo Leal | swift-init rest start |
| 606 | 45 | Beraldo Leal | </pre> |
| 607 | 45 | Beraldo Leal | |
| 608 | 45 | Beraldo Leal | |
| 609 | 45 | Beraldo Leal | h2. Verificando a instalacao |
| 610 | 45 | Beraldo Leal | |
| 611 | 45 | Beraldo Leal | O arquivo _/root/openstackrc_ vai receber novas variaveis de ambiente, ele deve ficar assim: |
| 612 | 45 | Beraldo Leal | |
| 613 | 45 | Beraldo Leal | <pre> |
| 614 | 45 | Beraldo Leal | # Used for Keystone |
| 615 | 45 | Beraldo Leal | export SERVICE_ENDPOINT=http://192.168.69.1:35357/v2.0/ |
| 616 | 45 | Beraldo Leal | export SERVICE_TOKEN=012345SECRET99TOKEN012345 |
| 617 | 45 | Beraldo Leal | |
| 618 | 45 | Beraldo Leal | # Used for swift |
| 619 | 45 | Beraldo Leal | export ST_AUTH=http://192.168.69.1:5000/v2.0 |
| 620 | 45 | Beraldo Leal | export ST_USER=openstackDemo:admin |
| 621 | 45 | Beraldo Leal | export ST_KEY=adminpass |
| 622 | 45 | Beraldo Leal | export OS_REGION_NAME=RegionOne |
| 623 | 45 | Beraldo Leal | </pre> |
| 624 | 45 | Beraldo Leal | |
| 625 | 45 | Beraldo Leal | Carregue o arquivo: |
| 626 | 45 | Beraldo Leal | |
| 627 | 45 | Beraldo Leal | <pre> |
| 628 | 45 | Beraldo Leal | # source /root/openstackrc |
| 629 | 45 | Beraldo Leal | </pre> |
| 630 | 45 | Beraldo Leal | |
| 631 | 45 | Beraldo Leal | Tente obter status do swift: |
| 632 | 45 | Beraldo Leal | |
| 633 | 45 | Beraldo Leal | <pre> |
| 634 | 45 | Beraldo Leal | # swift -V 2.0 stat |
| 635 | 45 | Beraldo Leal | </pre> |
| 636 | 45 | Beraldo Leal | |
| 637 | 45 | Beraldo Leal | # Liste os containers: |
| 638 | 45 | Beraldo Leal | |
| 639 | 45 | Beraldo Leal | <pre> |
| 640 | 45 | Beraldo Leal | # swift -V 2.0 list |
| 641 | 45 | Beraldo Leal | </pre> |
| 642 | 45 | Beraldo Leal | <pre> |