JClouds-Chef无法引导&配置虚拟机 [英] JClouds-Chef not bootstrapping & configuring VM

查看:108
本文介绍了JClouds-Chef无法引导&配置虚拟机的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取以下 JClouds-Chef 代码(v1.7.3)在全新的Linux VM上引导Chef Client,然后执行运行列表以使用应用程序堆栈(typical_app)实际配置该VM:

I am trying to get the following JClouds-Chef code (v1.7.3) to bootstrap Chef Client on a brand new Linux VM and then execute a run list to actually configure that VM with an app stack (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获得以下输出:

When I run this I get the following output from 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_8_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目录.这使我认为我的代码仅能部分工作,也许只能在VM上安装Ruby,而没有其他工作.除此之外,除非我在打印< and done!"语句之后放置System.exit(0),否则代码永远不会退出.这使我认为有一个后台/工作线程(也许是SSH进程在服务器上做某事)没有返回/完成.

When I SSH onto the server (myapp01), if I run which ruby I see that Ruby is installed. However which chef-client produces no output, and neither does which java. There is also no /etc/chef directory on the server. This makes me think that my code is only partially working, and perhaps only installing Ruby on the VM but nothing else. On top of this, unless I place a System.exit(0) after the "And done!" print statement, the code never exits. THis makes me think that there is a background/worker thread (maybe an SSH process doing something on the server) not returning/finishing.

这里没有抛出任何错误或异常.

There are no errors or exceptions that get thrown here.

我的问题:

  1. 有人可以看到为什么此代码无法正常工作(通过"正常工作",我的意思是,似乎只是部分安装了Chef Client,甚至没有安装Java,这是Java的一部分) typical_app角色)?
  2. 我是否在代码中缺少任何内容以防止后台线程完成?为什么它永远不会退出?
  1. Can anyone see why this code isn't working (by "working", I mean, seems to only be partially installing Chef Client, and is not even installing Java, which is a part of the typical_app role)?
  2. Am I missing anything in my code to prevent a background thread from finishing? Why does it never exit?

要进行复制,请使用以下Maven POM提取依赖项,然后按原样运行上面的代码(只需使用您自己的Chef服务器和Linux VM).

To reproduce, use the following Maven POM to pull down dependencies, and then run the code above, exactly as it is (just use your own Chef server and Linux VM).

<?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>

更新:这是我运行@Ignasi Barrera的建议更改后得到的/tmp/stderr文件:

Update: here is my /tmp/stderr file I get after running @Ignasi Barrera's suggested changes:

--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]

推荐答案

此处的主要挑战是您试图在节点上运行脚本而不使用jclouds计算服务.该代码使用jclouds-chef生成了一条Statement,但是假定该Statement由jclouds计算服务执行,该服务具有自己的机制来呈现其执行的脚本.

The main challenge here is that you're trying to run a script on a node without using the jclouds compute service. The code uses jclouds-chef to generate a Statement, but that Statement is assumed to be executed by the jclouds compute service, which has its own mechanisms to render the scripts it executes.

为了获得完整的原始脚本并能够使用原始SSH连接直接执行该脚本,必须手动完成一些操作.特别是,jclouds-chef脚本假定已定义了一些bash函数,而以这种方式呈现脚本时会丢失这些bash函数.

In order to get the complete raw script and to be able to execute it directly using a raw SSH connection, a few things must be done manually. In particular, the jclouds-chef script assumes a few bash functions are defined, and those are missing when rendering the script this way.

您应按以下步骤更改rawString字符串的创建:

You should change the creation of the rawString String as follows:

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("bash /tmp/chef-bootstrap.sh");

这样,最终脚本将具有所有相关功能.还要注意,我更改了代码以上传它,而不是直接运行该脚本,然后在本地运行该文件.这将帮助您解决脚本失败的情况.

This way the final script will have all the dependent functions. Also note that instead of directly running the script, I've changed the code to upload it, and then run the file locally. This will help you troubleshoot what is going on in case the script fails.

还请注意,该脚本将在每次运行时生成/etc/chef目录的内容,因此,在再次运行该脚本之前,您可能需要删除该目录.

Also note that the script will generate the contents of the /etc/chef directory on each run, so before running it again you might need to delete that directory.

这篇关于JClouds-Chef无法引导&amp;配置虚拟机的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆