All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.brooklyn.entity.chef.KnifeTaskFactory Maven / Gradle / Ivy

There is a newer version: 1.1.0
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.brooklyn.entity.chef;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Nullable;

import org.apache.brooklyn.api.entity.Entity;
import org.apache.brooklyn.config.ConfigKey;
import org.apache.brooklyn.core.mgmt.BrooklynTaskTags;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.core.internal.ssh.process.ProcessTool;
import org.apache.brooklyn.util.core.task.Tasks;
import org.apache.brooklyn.util.core.task.system.ProcessTaskFactory;
import org.apache.brooklyn.util.core.task.system.ProcessTaskWrapper;
import org.apache.brooklyn.util.core.task.system.internal.SystemProcessTaskFactory;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.text.StringEscapes.BashStringEscapes;

import com.google.common.base.Function;

/** A factory which acts like {@link ProcessTaskFactory} with special options for knife.
 * Typical usage is to {@link #addKnifeParameters(String)}s for the knife command to be run.
 * You can also {@link #add(String...)} commands as needed; these will run *before* knife,
 * unless you addKnifeCommandHere().
 * 

* This impl will use sensible defaults, including {@link ConfigKey}s on the context entity, * for general knife config but not specific commands etc. It supports: *

  • {@link ChefConfig#KNIFE_EXECUTABLE} *
  • {@link ChefConfig#KNIFE_CONFIG_FILE} *

    * (Other fields will typically be used by methods calling to this factory.) * */ // see e.g. http://docs.opscode.com/knife_bootstrap.html public class KnifeTaskFactory extends SystemProcessTaskFactory, RET>{ private static String KNIFE_PLACEHOLDER = ""; public final String taskName; protected String knifeExecutable; protected List knifeParameters = new ArrayList(); protected String knifeConfigFile; protected String knifeSetupCommands; protected Boolean throwOnCommonKnifeErrors; public KnifeTaskFactory(String taskName) { this.taskName = taskName; summary(taskName); // knife setup usually requires a login shell config.put(ProcessTool.PROP_LOGIN_SHELL, true); } @Override public List, Void>> getCompletionListeners() { MutableList, Void>> result = MutableList.copyOf(super.getCompletionListeners()); if (throwOnCommonKnifeErrors != Boolean.FALSE) insertKnifeCompletionListenerIntoCompletionListenersList(result); return result.asUnmodifiable(); } public KnifeTaskFactory notThrowingOnCommonKnifeErrors() { throwOnCommonKnifeErrors = false; return self(); } protected void insertKnifeCompletionListenerIntoCompletionListenersList(List, Void>> listeners) { // give a nice warning if chef/knife not set up correctly Function, Void> propagateIfKnifeConfigFileMissing = new Function, Void>() { @Override public Void apply(@Nullable ProcessTaskWrapper input) { if (input.getExitCode()!=0 && input.getStderr().indexOf("WARNING: No knife configuration file found")>=0) { String myConfig = knifeConfigFileOption(); if (Strings.isEmpty(myConfig)) throw new IllegalStateException("Config file for Chef knife must be specified in "+ChefConfig.KNIFE_CONFIG_FILE+" (or valid knife default set up)"); else throw new IllegalStateException("Error reading config file for Chef knife ("+myConfig+") -- does it exist?"); } return null; } }; listeners.add(propagateIfKnifeConfigFileMissing); } @Override public ProcessTaskWrapper newTask() { return new SystemProcessTaskWrapper("Knife"); } /** Inserts the knife command at the current place in the list. * Can be run multiple times. The knife command added at the end of the list * if this is not invoked (and it is the only command if nothing is {@link #add(String...)}ed. */ public KnifeTaskFactory addKnifeCommandToScript() { add(KNIFE_PLACEHOLDER); return self(); } @Override public List getCommands() { MutableList result = new MutableList(); String setupCommands = knifeSetupCommands(); if (setupCommands != null && Strings.isNonBlank(setupCommands)) result.add(setupCommands); int numKnifes = 0; for (String c: super.getCommands()) { if (c==KNIFE_PLACEHOLDER) result.add(buildKnifeCommand(numKnifes++)); else result.add(c); } if (numKnifes==0) result.add(buildKnifeCommand(numKnifes++)); return result.asUnmodifiable(); } /** creates the command for running knife. * in some cases knife may be added multiple times, * and in that case the parameter here tells which time it is being added, * on a single run. */ protected String buildKnifeCommand(int knifeCommandIndex) { MutableList words = new MutableList(); words.add(knifeExecutable()); words.addAll(initialKnifeParameters()); words.addAll(knifeParameters()); String x = knifeConfigFileOption(); if (Strings.isNonBlank(x)) words.add(knifeConfigFileOption()); return Strings.join(words, " "); } /** allows a way for subclasses to build up parameters at the start */ protected List initialKnifeParameters() { return new MutableList(); } @Nullable /** callers should allow this to be null so task can be used outside of an entity */ protected Entity entity() { return BrooklynTaskTags.getTargetOrContextEntity(Tasks.current()); } protected T entityConfig(ConfigKey key) { Entity entity = entity(); if (entity!=null) return entity.getConfig(key); return null; } public KnifeTaskFactory knifeExecutable(String knifeExecutable) { this.knifeExecutable = knifeExecutable; return this; } protected String knifeExecutable() { if (knifeExecutable!=null) return knifeExecutable; String knifeExecFromConfig = entityConfig(ChefConfig.KNIFE_EXECUTABLE); if (knifeExecFromConfig!=null) return BashStringEscapes.wrapBash(knifeExecFromConfig); // assume on the path, if executable not set return "knife"; } protected List knifeParameters() { return knifeParameters; } public KnifeTaskFactory knifeAddParameters(String word1, String ...words) { knifeParameters.add(word1); for (String w: words) knifeParameters.add(w); return self(); } public KnifeTaskFactory knifeConfigFile(String knifeConfigFile) { this.knifeConfigFile = knifeConfigFile; return self(); } @Nullable protected String knifeConfigFileOption() { if (knifeConfigFile!=null) return "-c "+knifeConfigFile; String knifeConfigFileFromConfig = entityConfig(ChefConfig.KNIFE_CONFIG_FILE); if (knifeConfigFileFromConfig!=null) return "-c "+BashStringEscapes.wrapBash(knifeConfigFileFromConfig); // if not supplied will use global config return null; } public KnifeTaskFactory knifeSetupCommands(String knifeSetupCommands) { this.knifeSetupCommands = knifeSetupCommands; return self(); } @Nullable protected String knifeSetupCommands() { if (knifeSetupCommands!=null) return knifeSetupCommands; String knifeSetupCommandsFromConfig = entityConfig(ChefConfig.KNIFE_SETUP_COMMANDS); if (knifeSetupCommandsFromConfig!=null) return knifeSetupCommandsFromConfig; // if not supplied will use global config return null; } @Override public KnifeTaskFactory returning(ScriptReturnType type) { return (KnifeTaskFactory) super.returning(type); } @Override public KnifeTaskFactory returning(Function, RET2> resultTransformation) { return (KnifeTaskFactory) super.returning(resultTransformation); } @Override public KnifeTaskFactory returningIsExitCodeZero() { return (KnifeTaskFactory) super.returningIsExitCodeZero(); } @Override public KnifeTaskFactory requiringZeroAndReturningStdout() { return (KnifeTaskFactory) super.requiringZeroAndReturningStdout(); } }





  • © 2015 - 2024 Weber Informatics LLC | Privacy Policy