Я пытаюсь получить следующий код JClouds-Chef (v1.7.3) для начальной загрузки клиента Chef. на совершенно новой виртуальной машине Linux, а затем выполните список запуска, чтобы фактически настроить эту виртуальную машину со стеком приложений (typical_app
):
public class ChefPlugin {
public static void main(String[] args) {
ChefPlugin.provision();
System.out.println("And done!");
System.exit(0);
}
public static provision() {
String vmIp = "myapp01";
String vmSshUsername = "myadmin";
String vmSshPassword = "12345";
String endpoint = "https://mychefserver";
String client = "myuser";
String validator = "chef-validator";
String clientCredential = Files.toString(new File("C:\\Users\\myuser\\sandbox\\chef\\myuser.pem"), Charsets.UTF_8);
String validatorCredential = Files.toString(new File("C:\\Users\\myuser\\sandbox\\chef\\chef-validator.pem"), Charsets.UTF_8);
Properties props = new Properties();
props.put(ChefProperties.CHEF_VALIDATOR_NAME, validator);
props.put(ChefProperties.CHEF_VALIDATOR_CREDENTIAL, validatorCredential);
props.put(Constants.PROPERTY_RELAX_HOSTNAME, "true");
props.put(Constants.PROPERTY_TRUST_ALL_CERTS, "true");
System.out.println("Setup complete.");
ChefContext ctx = ContextBuilder.newBuilder("chef")
.endpoint(endpoint)
.credentials(client, clientCredential)
.overrides(props)
.modules(ImmutableSet.of(new SshjSshClientModule())) //
.buildView(ChefContext.class);
ChefService chef = ctx.getChefService();
List<String> runlist = new RunListBuilder().addRole("typicalapp").build();
ArrayList<String> runList2 = new ArrayList<String>();
for(String item : runlist) {
runList2.add(item);
}
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().runList(runList2).build();
System.out.println("Configured the bootstrapper.");
chef.updateBootstrapConfigForGroup("jclouds-chef", bootstrapConfig);
Statement bootstrap = chef.createBootstrapScriptForGroup("jclouds-chef");
SshClient.Factory sshFactory = ctx.unwrap().utils()
.injector().getInstance(Key.get(new TypeLiteral<SshClient.Factory>() {}));
SshClient ssh = sshFactory.create(HostAndPort.fromParts(vmIp, 22),
LoginCredentials.builder().user(vmSshUsername).password(vmSshPassword).build());
ssh.connect();
System.out.println("Connected to SSH.");
try {
String rawScript = bootstrap.render(OsFamily.UNIX);
System.out.println("Raw script rendered.");
ExecResponse result = ssh.exec(rawScript);
System.out.println("Bootstrap script executed...");
} catch(Throwable t) {
System.out.println("Exception: " + t.getMessage());
} finally {
ssh.disconnect();
System.out.println("SSH closed.");
}
}
}
Когда я запускаю это, я получаю следующий вывод от SLF4J:
Setup complete.
Configured the bootstrapper.
[main] INFO net.schmizz.sshj.common.SecurityUtils - BouncyCastle registration succeeded
[main] WARN net.schmizz.sshj.DefaultConfig - Disabling high-strength ciphers: cipher strengths apparently limited by JCE policy
[main] INFO net.schmizz.sshj.transport.TransportImpl - Client identity string: SSH-2.0-SSHJ_0/etc/chef
1_SNAPSHOT
[main] INFO net.schmizz.sshj.transport.TransportImpl - Server identity string: SSH-2.0-OpenSSH_6.6p1 Ubuntu-2ubuntu1
Connected to SSH.
Raw script rendered.
[main] INFO net.schmizz.sshj.connection.channel.direct.SessionChannel - Will request to exec `setupPublicCurl || exit 1
curl -q -s -S -L --connect-timeout 10 --max-time 600 --retry 20 -X GET https://www.opscode.com/chef/install.sh |(bash)
mkdir -p /etc/chef
cat >> /etc/chef/client.rb <<-'END_OF_JCLOUDS_FILE'
require 'rubygems'
require 'ohai'
o = Ohai::System.new
o.all_plugins
node_name "jclouds-chef-" + o[:ipaddress]
log_level :info
log_location STDOUT
validation_client_name "chef-validator"
chef_server_url "https://mychefserver"
END_OF_JCLOUDS_FILE
cat >> /etc/chef/validation.pem <<-'END_OF_JCLOUDS_FILE'
-----BEGIN RSA PRIVATE KEY-----
<omitted for security purposes>
-----END RSA PRIVATE KEY-----
END_OF_JCLOUDS_FILE
cat >> /etc/chef/first-boot.json <<-'END_OF_JCLOUDS_FILE'
{"id":"jclouds-chef","run_list":["role[typical_app]"]}
END_OF_JCLOUDS_FILE
chef-client -j /etc/chef/first-boot.json
`
Bootstrap script executed...
[main] INFO net.schmizz.sshj.transport.TransportImpl - Disconnected - BY_APPLICATION
SSH closed.
And done!
Когда я подключаюсь по SSH к серверу (myapp01
), если я запускаю which ruby
, я вижу, что Ruby установлен. Однако which chef-client
не производит вывода, как и which java
. На сервере также нет каталога /etc/chef
. Это заставляет меня думать, что мой код работает лишь частично и, возможно, только устанавливает Ruby на виртуальную машину, но больше ничего. Вдобавок ко всему, если я не поставлю System.exit(0)
после оператора печати "И готово!", код никогда не завершится. Это заставляет меня думать, что есть фоновый/рабочий поток (возможно, процесс SSH что-то делает на сервере), который не возвращается/не завершается.
Здесь нет ошибок или исключений.
Мои вопросы:
- Может ли кто-нибудь понять, почему этот код не работает (под "работает" я имею в виду, кажется, только частично устанавливает Chef Client и даже не устанавливает Java, которая является частью роли
typical_app
)? - Я что-то упустил в своем коде, чтобы предотвратить завершение фонового потока? Почему он никогда не выходит?
Чтобы воспроизвести, используйте следующий Maven POM для извлечения зависимостей, а затем запустите приведенный выше код точно так, как он есть (просто используйте свой собственный сервер Chef и виртуальную машину Linux).
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<properties>
<jclouds.version>1.7.3</jclouds.version>
</properties>
<groupId>com.mycompany.app</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.jclouds.driver</groupId>
<artifactId>jclouds-sshj</artifactId>
<version>${jclouds.version}</version>
</dependency>
<dependency>
<groupId>org.apache.jclouds.api</groupId>
<artifactId>chef</artifactId>
<version>${jclouds.version}</version>
</dependency>
</dependencies>
</project>
Обновление: вот мой файл /tmp/stderr
, который я получил после внесения изменений, предложенных @Ignasi Barrera:
--2014-07-22 10:58:14-- https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/13.04/x86_64/chef_11.12.8-2_amd64.deb
Resolving opscode-omnibus-packages.s3.amazonaws.com (opscode-omnibus-packages.s3.amazonaws.com)... 176.32.100.240
Connecting to opscode-omnibus-packages.s3.amazonaws.com (opscode-omnibus-packages.s3.amazonaws.com)|176.32.100.240|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 33399362 (32M) [application/x-debian-package]
Saving to: ‘/tmp/install.sh.10185/chef_11.12.8-2_amd64.deb’
0K .......... .......... .......... .......... .......... 0% 908K 36s
50K .......... .......... .......... .......... .......... 0% 1.13M 32s
100K .......... .......... .......... .......... .......... 0% 26.9M 22s
150K .......... .......... .......... .......... .......... 0% 1.36M 22s
200K .......... .......... .......... .......... .......... 0% 17.2M 18s
... omitted for brevity
32400K .......... .......... .......... .......... .......... 99% 2.64M 0s
32450K .......... .......... .......... .......... .......... 99% 26.2M 0s
32500K .......... .......... .......... .......... .......... 99% 31.9M 0s
32550K .......... .......... .......... .......... .......... 99% 6.12M 0s
32600K .......... ...... 100% 4.09M=7.1s
2014-07-22 10:58:22 (4.49 MB/s) - ‘/tmp/install.sh.10185/chef_11.12.8-2_amd64.deb’ saved [33399362/33399362]