I have been using the following JClouds-Chef 1.7.3 code for several months now to bootstrap new VMs from scratch:
public class Bootstrapper {
public static void main(String[] args) {
Bootstrapper b = new Bootstrapper();
b.bootstrap();
}
public void bootstrap() {
String endpoint = "https://mychef.example.com"
String client = "myuser"
String validator = "chef-validator"
String clientCredential = Files.toString(new File("/etc/myuser/myuser.pem"), Charsets.UTF_8)
String validatorCredential = Files.toString(new File("/etc/myuser/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")
ChefContext ctx = ContextBuilder.newBuilder("chef")
.endpoint(endpoint)
.credentials(client, clientCredential)
.overrides(props)
.modules(ImmutableSet.of(new SshjSshClientModule())) //
.buildView(ChefContext.class);
ChefApi api = ctx.unwrapApi(ChefApi.class)
MyEnvProvider environmentProvider = new MyEnvProvider()
Environment devEnv = environmentProvider.provideEnvironment()
api.createEnvironment(devEnv)
List<String> runlist = new RunListBuilder().addRole("myrole").build()
BootstrapConfig bootstrapConfig = BootstrapConfig.builder().environment("myenv").runList(runlist).build()
String vmIp = "myapp01.example.com"
String vmSshUsername = "myuser"
String vmSshPassword = "12345"
ChefService chef = chefContext.getChefService()
chef.updateBootstrapConfigForGroup(chefGroup, bootstrapConfig)
Statement bootstrap = chef.createBootstrapScriptForGroup(chefGroup)
SshClient.Factory sshFactory = chefContext.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()
StringBuilder rawScript = new StringBuilder()
Map<String, String> resolvedFunctions = ScriptBuilder.resolveFunctionDependenciesForStatements(
new HashMap<String, String>(), ImmutableSet.of(bootstrap), OsFamily.UNIX)
ScriptBuilder.writeFunctions(resolvedFunctions, OsFamily.UNIX, rawScript)
rawScript.append(bootstrap.render(OsFamily.UNIX))
ssh.put("/tmp/chef-bootstrap.sh", rawScript.toString())
ExecResponse result = ssh.exec("sudo bash /tmp/chef-bootstrap.sh")
ssh.disconnect()
api.close()
ctx.close()
}
}
I just ran this code for the first time in several weeks, and everything is broken. It seems this code now results with nodes that use Chef 12, whereas mychef.example.com
is a Chef 11 server, and this is the root of the issue.
So I ask: How do I configure this code so that it continues to install/bootstrap Chef 11.x nodes?
Please note: This is a code question, not a systems admin question, and as such belong on StackOverflow.
The jclouds docs list how to configure the process.
In this case you would want something like ChefProperties.CHEF_VERSION = '11.16.4'
. I feel like I should point out that chef-client 12 works just fine with Chef Server 11. If you are running Enterprise Chef 11 you just need to update a config variable on it to allow client 12, as it was incorrectly limited to only 11.x.