You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by al...@apache.org on 2015/04/01 23:46:20 UTC
[1/3] incubator-brooklyn git commit: System Service enricher
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master 63c03b15e -> 1f1491740
System Service enricher
Installs the entity being enriched as a system service. Saves the launch script and uses it to start the entity.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/ac42ffc1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/ac42ffc1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/ac42ffc1
Branch: refs/heads/master
Commit: ac42ffc1dbff8fce6f466fcde3d9a24ccfc4c116
Parents: 0ff4216
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Tue Mar 17 20:08:49 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Mar 31 14:33:04 2015 +0300
----------------------------------------------------------------------
.../entity/service/EntityLaunchListener.java | 111 ++++++++++++++
.../entity/service/InitdServiceInstaller.java | 135 ++++++++++++++++
.../entity/service/SystemServiceEnricher.java | 152 +++++++++++++++++++
.../entity/service/SystemServiceInstaller.java | 25 +++
.../service/SystemServiceInstallerFactory.java | 28 ++++
.../brooklyn/entity/service/service.sh | 51 +++++++
6 files changed, 502 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/java/brooklyn/entity/service/EntityLaunchListener.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/EntityLaunchListener.java b/software/base/src/main/java/brooklyn/entity/service/EntityLaunchListener.java
new file mode 100644
index 0000000..a374ffe
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/service/EntityLaunchListener.java
@@ -0,0 +1,111 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicReference;
+
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.BrooklynTaskTags.EffectorCallTag;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.event.SensorEvent;
+import brooklyn.event.SensorEventListener;
+import brooklyn.management.ExecutionManager;
+import brooklyn.management.Task;
+import brooklyn.util.task.Tasks;
+
+public class EntityLaunchListener implements Runnable, SensorEventListener<Lifecycle> {
+ private static final String SSH_LAUNCH_TASK_PREFIX = "ssh: launching";
+ private static final String LAUNCH_CHECK_SKIP_TAG = "system-service-update";
+
+ private final AtomicReference<Task<?>> launchTaskRef = new AtomicReference<Task<?>>();
+ private final SystemServiceEnricher enricher;
+
+ public EntityLaunchListener(SystemServiceEnricher enricher) {
+ this.enricher = checkNotNull(enricher, "enricher");
+ }
+
+ @Override
+ public void onEvent(SensorEvent<Lifecycle> event) {
+ if (event.getValue() == Lifecycle.RUNNING) {
+ Task<?>launchTask = getLatestLaunchTask(enricher.getEntity());
+ if (launchTask != null) {
+ launchTaskRef.set(launchTask);
+ if (!launchTask.isDone()) {
+ launchTask.addListener(this, enricher.getEntityExecutionContext());
+ }
+ if (launchTask.isDone()) {
+ run();
+ }
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ Task<?> launchTask = launchTaskRef.getAndSet(null);
+ if (launchTask == null) return;
+ if (launchTask.isError()) return;
+ enricher.onLaunched(launchTask);
+ }
+
+ private Task<?> getLatestLaunchTask(Entity entity) {
+ Task<?> startEffector = null;
+ ExecutionManager executionmgr = enricher.getManagementContext().getExecutionManager();
+ Set<Task<?>> entityTasks = BrooklynTaskTags.getTasksInEntityContext(executionmgr, entity);
+ for (Task<?> t : entityTasks) {
+ if (BrooklynTaskTags.isEffectorTask(t)) {
+ EffectorCallTag effectorTag = BrooklynTaskTags.getEffectorCallTag(t, false);
+ if (SystemServiceEnricher.LAUNCH_EFFECTOR_NAMES.contains(effectorTag.getEffectorName()) &&
+ !BrooklynTaskTags.hasTag(t, LAUNCH_CHECK_SKIP_TAG)) {
+ if (startEffector == null || startEffector.getStartTimeUtc() < t.getStartTimeUtc()) {
+ startEffector = t;
+ }
+ BrooklynTaskTags.addTagDynamically(t, LAUNCH_CHECK_SKIP_TAG);
+ }
+ }
+ }
+ if (startEffector != null) {
+ Task<?> launchTask = findSshLaunchChild(startEffector);
+ if (launchTask != null) {
+ return launchTask;
+ }
+ }
+ return null;
+ }
+
+ private Task<?> findSshLaunchChild(Task<?> t) {
+ Iterable<Task<?>> children = Tasks.children(t);
+ for (Task<?> c : children) {
+ if (c.getDisplayName().startsWith(SSH_LAUNCH_TASK_PREFIX)) {
+ return c;
+ }
+ }
+ for (Task<?> c : children) {
+ Task<?> launchTask = findSshLaunchChild(c);
+ if (launchTask != null) {
+ return launchTask;
+ }
+ }
+ return null;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java b/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
new file mode 100644
index 0000000..ce52038
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/service/InitdServiceInstaller.java
@@ -0,0 +1,135 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.util.Map;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.EntityInternal;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.effector.EffectorTasks;
+import brooklyn.entity.trait.HasShortName;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.location.cloud.CloudMachineNamer;
+import brooklyn.management.Task;
+import brooklyn.policy.Enricher;
+import brooklyn.util.ResourceUtils;
+import brooklyn.util.collections.MutableMap;
+import brooklyn.util.os.Os;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.task.Tasks;
+import brooklyn.util.task.ssh.SshPutTaskWrapper;
+import brooklyn.util.task.ssh.SshTasks;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+import brooklyn.util.text.TemplateProcessor;
+
+
+public class InitdServiceInstaller implements SystemServiceInstaller {
+ private static final ConfigKey<String> SERVICE_TEMPLATE = ConfigKeys.newStringConfigKey(
+ "service.initd.service_template", "URL of the template to be used as the /etc/init.d service", "classpath:///brooklyn/entity/service/service.sh");
+
+ private final Entity entity;
+ private final Enricher enricher;
+
+ public InitdServiceInstaller(Entity entity, Enricher enricher) {
+ this.entity = checkNotNull(entity, "entity");
+ this.enricher = checkNotNull(enricher, "enricher");
+ }
+
+ @Override
+ public Task<?> getServiceInstallTask() {
+ ResourceUtils resource = new ResourceUtils(this);
+ String pidFile = entity.getAttribute(SoftwareProcess.PID_FILE);
+ String template = resource.getResourceAsString(enricher.config().get(SERVICE_TEMPLATE));
+ String serviceName = getServiceName();
+ SshMachineLocation sshMachine = EffectorTasks.getSshMachine(entity);
+ Map<String, Object> params = MutableMap.<String, Object>of(
+ "service.launch_script", Os.mergePaths(getRunDir(), getStartScriptName()),
+ "service.name", serviceName,
+ "service.user", sshMachine.getUser(),
+ "service.log_path", getLogLocation());
+ if (pidFile != null) {
+ params.put("service.pid_file", pidFile);
+ }
+ String service = TemplateProcessor.processTemplateContents(template, (EntityInternal)entity, params);
+ String tmpServicePath = Os.mergePaths(getRunDir(), serviceName);
+ String servicePath = "/etc/init.d/" + serviceName;
+ SshPutTaskWrapper putServiceTask = SshTasks.newSshPutTaskFactory(sshMachine, tmpServicePath)
+ .contents(service)
+ .newTask();
+ ProcessTaskWrapper<Integer> installServiceTask = SshTasks.newSshExecTaskFactory(sshMachine,
+ BashCommands.chain(
+ BashCommands.sudo("mv " + tmpServicePath + " " + servicePath),
+ BashCommands.sudo("chmod 0755 " + servicePath),
+ BashCommands.sudo("chkconfig --add " + serviceName),
+ BashCommands.sudo("chkconfig " + serviceName + " on")))
+ .requiringExitCodeZero()
+ .newTask();
+
+ return Tasks.<Void>builder()
+ .name("install (init.d)")
+ .description("Install init.d service")
+ .add(putServiceTask)
+ .add(installServiceTask)
+ .build();
+ }
+
+ private String getServiceName() {
+ String serviceNameTemplate = enricher.config().get(SystemServiceEnricher.SERVICE_NAME);
+ return serviceNameTemplate
+ .replace("${id}", entity.getId())
+ .replace("${entity_name}", getEntityName());
+ }
+
+ private CharSequence getEntityName() {
+ String name;
+ if (entity instanceof HasShortName) {
+ name = ((HasShortName)entity).getShortName();
+ } else if (entity instanceof Entity) {
+ name = ((Entity)entity).getDisplayName();
+ } else {
+ name = "brooklyn-service";
+ }
+ return CloudMachineNamer.sanitize(name.toString()).toLowerCase();
+ }
+
+ private String getStartScriptName() {
+ return enricher.config().get(SystemServiceEnricher.LAUNCH_SCRIPT_NAME);
+ }
+
+ private String getRunDir() {
+ return entity.getAttribute(SoftwareProcess.RUN_DIR);
+ }
+
+ private String getLogLocation() {
+ String logFileLocation = entity.getAttribute(Attributes.LOG_FILE_LOCATION);
+ if (logFileLocation != null) {
+ return new File(logFileLocation).getParent();
+ } else {
+ return "/tmp";
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java b/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
new file mode 100644
index 0000000..e47e375
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/service/SystemServiceEnricher.java
@@ -0,0 +1,152 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import java.util.Set;
+
+import brooklyn.config.ConfigKey;
+import brooklyn.enricher.basic.AbstractEnricher;
+import brooklyn.entity.Entity;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.BrooklynTaskTags;
+import brooklyn.entity.basic.BrooklynTaskTags.WrappedStream;
+import brooklyn.entity.basic.ConfigKeys;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityLocal;
+import brooklyn.entity.basic.SoftwareProcess;
+import brooklyn.entity.effector.EffectorTasks;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.management.ExecutionContext;
+import brooklyn.management.Task;
+import brooklyn.policy.Enricher;
+import brooklyn.util.net.Urls;
+import brooklyn.util.task.BasicExecutionManager;
+import brooklyn.util.task.DynamicTasks;
+import brooklyn.util.task.TaskBuilder;
+import brooklyn.util.task.ssh.SshPutTaskWrapper;
+import brooklyn.util.task.ssh.SshTasks;
+import brooklyn.util.task.system.ProcessTaskFactory;
+import brooklyn.util.task.system.ProcessTaskWrapper;
+
+import com.google.common.collect.ImmutableSet;
+
+public class SystemServiceEnricher extends AbstractEnricher implements Enricher {
+ public static final String DEFAULT_ENRICHER_UNIQUE_TAG = "systemService.tag";
+ protected static final Set<String> LAUNCH_EFFECTOR_NAMES = ImmutableSet.of("start", "restart");
+ public static final ConfigKey<String> LAUNCH_SCRIPT_NAME = ConfigKeys.newStringConfigKey(
+ "service.script_name", "The name of the launch script to be created in the runtime directory of the entity.", "service-launch.sh");
+ public static final ConfigKey<String> SERVICE_NAME = ConfigKeys.newStringConfigKey(
+ "service.name", "The name of the system service. Can use ${entity_name} and ${id} variables to template the value.", "${entity_name}-${id}");
+
+ @Override
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ subscribeLaunch();
+ uniqueTag = DEFAULT_ENRICHER_UNIQUE_TAG;
+ }
+
+ private void subscribeLaunch() {
+ subscribe(entity, Attributes.SERVICE_STATE_ACTUAL, new EntityLaunchListener(this));
+ }
+
+ public void onLaunched(Task<?> task) {
+ WrappedStream streamStdin = BrooklynTaskTags.stream(task, BrooklynTaskTags.STREAM_STDIN);
+ if (streamStdin == null) return;
+
+ WrappedStream streamEnv = BrooklynTaskTags.stream(task, BrooklynTaskTags.STREAM_ENV);
+ String stdin = streamStdin.streamContents.get();
+ String env = streamEnv.streamContents.get();
+
+ final SshMachineLocation sshMachine = EffectorTasks.getSshMachine(entity);
+ final String launchScriptPath = Urls.mergePaths(getRunDir(), getStartScriptName());
+
+ Task<Void> installerTask = TaskBuilder.<Void>builder()
+ .name("install (service)")
+ .description("Install as a system service")
+ .body(new Runnable() {
+ @Override
+ public void run() {
+ ProcessTaskFactory<Integer> taskFactory = SshTasks.newSshExecTaskFactory(sshMachine, "[ -e '" + launchScriptPath + "' ]")
+ .summary("check installed")
+ .allowingNonZeroExitCode();
+ boolean isInstalled = DynamicTasks.queue(taskFactory).get() == 0;
+ if (!isInstalled) {
+ Task<?> serviceInstallTask = SystemServiceInstallerFactory.of(entity, SystemServiceEnricher.this).getServiceInstallTask();
+ DynamicTasks.queue(serviceInstallTask);
+ }
+ }
+ })
+ .build();
+
+ SshPutTaskWrapper updateLaunchScriptTask = SshTasks.newSshPutTaskFactory(sshMachine, launchScriptPath).contents(getLaunchScript(stdin, env)).newTask();
+ ProcessTaskWrapper<Integer> makeExecutableTask = SshTasks.newSshExecTaskFactory(sshMachine, "chmod +x " + launchScriptPath)
+ .requiringExitCodeZero()
+ .newTask();
+ Task<Void> udpateTask = TaskBuilder.<Void>builder()
+ .name("update-launch")
+ .description("Update launch script used by the system service")
+ .add(updateLaunchScriptTask)
+ .add(makeExecutableTask)
+ .build();
+
+ Task<Void> updateService = TaskBuilder.<Void>builder()
+ .name("update-system-service")
+ .description("Update system service")
+ .add(installerTask)
+ .add(udpateTask)
+ .tag(BrooklynTaskTags.tagForContextEntity(entity))
+ .tag(BrooklynTaskTags.NON_TRANSIENT_TASK_TAG)
+ .build();
+
+ submitTopLevel(updateService);
+ }
+
+ private void submitTopLevel(Task<Void> updateService) {
+ Task<?> currentTask = BasicExecutionManager.getPerThreadCurrentTask().get();
+ BasicExecutionManager.getPerThreadCurrentTask().set(null);
+ try {
+ Entities.submit(entity, updateService);
+ } finally {
+ BasicExecutionManager.getPerThreadCurrentTask().set(currentTask);
+ }
+ }
+
+ private String getLaunchScript(String stdin, String env) {
+ // (?m) - multiline enable
+ // insert export at beginning of each line
+ return env.replaceAll("(?m)^", "export ") + "\n" + stdin;
+ }
+
+ private String getRunDir() {
+ return entity.getAttribute(SoftwareProcess.RUN_DIR);
+ }
+
+ private String getStartScriptName() {
+ return config().get(LAUNCH_SCRIPT_NAME);
+ }
+
+ ExecutionContext getEntityExecutionContext() {
+ return getManagementContext().getExecutionContext(entity);
+ }
+
+ protected Entity getEntity() {
+ return entity;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstaller.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstaller.java b/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstaller.java
new file mode 100644
index 0000000..a4d8b6d
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstaller.java
@@ -0,0 +1,25 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import brooklyn.management.Task;
+
+public interface SystemServiceInstaller {
+ Task<?> getServiceInstallTask();
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstallerFactory.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstallerFactory.java b/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstallerFactory.java
new file mode 100644
index 0000000..08da83a
--- /dev/null
+++ b/software/base/src/main/java/brooklyn/entity/service/SystemServiceInstallerFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import brooklyn.entity.Entity;
+import brooklyn.policy.Enricher;
+
+public class SystemServiceInstallerFactory {
+ public static SystemServiceInstaller of(Entity entity, Enricher systemServiceEnricher) {
+ return new InitdServiceInstaller(entity, systemServiceEnricher);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/ac42ffc1/software/base/src/main/resources/brooklyn/entity/service/service.sh
----------------------------------------------------------------------
diff --git a/software/base/src/main/resources/brooklyn/entity/service/service.sh b/software/base/src/main/resources/brooklyn/entity/service/service.sh
new file mode 100644
index 0000000..4a1b293
--- /dev/null
+++ b/software/base/src/main/resources/brooklyn/entity/service/service.sh
@@ -0,0 +1,51 @@
+#!/usr/bin/env bash
+#
+# 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.
+#
+# chkconfig: - 80 20
+#
+### BEGIN INIT INFO
+# Provides: ${service.name}
+# Required-Start: $network $syslog
+# Required-Stop: $network $syslog
+# Default-Start:
+# Default-Stop:
+# Short-Description: Brooklyn entity service
+# Description: Service for Brooklyn managed entity
+### END INIT INFO
+
+case $1 in
+ start)
+ touch ${service.log_path}/${service.name}.log
+ chown ${service.user} ${service.log_path}/${service.name}.log
+ sudo -u ${service.user} ${service.launch_script} >> ${service.log_path}/${service.name}.log 2>&1
+ ;;
+# stop)
+# ;;
+# restart)
+# ;;
+# status)
+# ;;
+# reload)
+# ;;
+ *)
+# echo "Usage: $0 {start|stop|restart|reload|status}"
+ echo "Usage: $0 {start}"
+ exit 2
+ ;;
+esac
[2/3] incubator-brooklyn git commit: Test for the system service
installer
Posted by al...@apache.org.
Test for the system service installer
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/6470cc51
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/6470cc51
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/6470cc51
Branch: refs/heads/master
Commit: 6470cc511469defac92b794645486ed2b8fd6544
Parents: ac42ffc
Author: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Authored: Wed Mar 25 12:29:54 2015 +0200
Committer: Svetoslav Neykov <sv...@cloudsoftcorp.com>
Committed: Tue Mar 31 14:33:12 2015 +0300
----------------------------------------------------------------------
.../service/SystemServiceEnricherTest.java | 95 ++++++++++++++++++++
1 file changed, 95 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/6470cc51/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
----------------------------------------------------------------------
diff --git a/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java b/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
new file mode 100644
index 0000000..6436fa9
--- /dev/null
+++ b/software/base/src/test/java/brooklyn/entity/service/SystemServiceEnricherTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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 brooklyn.entity.service;
+
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import brooklyn.entity.BrooklynAppLiveTestSupport;
+import brooklyn.entity.basic.Attributes;
+import brooklyn.entity.basic.Entities;
+import brooklyn.entity.basic.EntityPredicates;
+import brooklyn.entity.basic.Lifecycle;
+import brooklyn.entity.basic.VanillaSoftwareProcess;
+import brooklyn.entity.basic.VanillaSoftwareProcessImpl;
+import brooklyn.entity.basic.VanillaSoftwareProcessSshDriver;
+import brooklyn.entity.effector.EffectorTasks;
+import brooklyn.entity.proxying.EntitySpec;
+import brooklyn.location.basic.SshMachineLocation;
+import brooklyn.location.jclouds.JcloudsLocation;
+import brooklyn.policy.EnricherSpec;
+import brooklyn.test.Asserts;
+import brooklyn.util.ssh.BashCommands;
+import brooklyn.util.time.Duration;
+
+import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+public class SystemServiceEnricherTest extends BrooklynAppLiveTestSupport {
+ //requires /etc/init.d OS, for example CentOS 6.5
+ private static final String LOCATION_SPEC = "named:service-live-test-location";
+ private JcloudsLocation location;
+
+ @Override
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+ location = (JcloudsLocation) mgmt.getLocationRegistry().resolve(LOCATION_SPEC);
+ }
+
+ @Test(groups = "Live")
+ public void testRestartLaunchesService() {
+ String launchCmd = "nohup bash -c \"echo \\$\\$ > $PID_FILE; while true; do sleep 1000; done\" &";
+ EntitySpec<VanillaSoftwareProcess> procSpec = EntitySpec.create(VanillaSoftwareProcess.class)
+ .configure(VanillaSoftwareProcess.LAUNCH_COMMAND, launchCmd)
+ .enricher(EnricherSpec.create(SystemServiceEnricher.class));
+ VanillaSoftwareProcess proc = app.createAndManageChild(procSpec);
+ app.start(ImmutableList.of(location));
+
+ waitHealthy(proc);
+
+ SshMachineLocation machine = EffectorTasks.getSshMachine(proc);
+ String pidFile = getPidFile(proc);
+ String killCmd = "kill -9 `cat " + pidFile + "`";
+ machine.execCommands("kill process", ImmutableList.of(killCmd));
+
+ waitFailed(proc);
+
+ int restartCode = machine.execCommands("restart machine", ImmutableList.of(BashCommands.sudo("/sbin/shutdown -r now")));
+ assertEquals(restartCode, 0);
+
+ waitHealthy(proc);
+ }
+
+ private String getPidFile(VanillaSoftwareProcess proc) {
+ VanillaSoftwareProcessImpl impl = (VanillaSoftwareProcessImpl)Entities.deproxy(proc);
+ return ((VanillaSoftwareProcessSshDriver)impl.getDriver()).getPidFile();
+ }
+
+ private void waitFailed(VanillaSoftwareProcess proc) {
+ Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE));
+ }
+
+ private void waitHealthy(VanillaSoftwareProcess proc) {
+ Asserts.eventually(ImmutableMap.of("timeout", Duration.FIVE_MINUTES), Suppliers.ofInstance(proc), EntityPredicates.attributeEqualTo(Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING));
+ }
+}
[3/3] incubator-brooklyn git commit: This closes #556
Posted by al...@apache.org.
This closes #556
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/1f149174
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/1f149174
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/1f149174
Branch: refs/heads/master
Commit: 1f1491740ca8b3442eb6f75788449e0288edad5a
Parents: 63c03b1 6470cc5
Author: Aled Sage <al...@gmail.com>
Authored: Wed Apr 1 22:46:04 2015 +0100
Committer: Aled Sage <al...@gmail.com>
Committed: Wed Apr 1 22:46:04 2015 +0100
----------------------------------------------------------------------
.../entity/service/EntityLaunchListener.java | 111 ++++++++++++++
.../entity/service/InitdServiceInstaller.java | 135 ++++++++++++++++
.../entity/service/SystemServiceEnricher.java | 152 +++++++++++++++++++
.../entity/service/SystemServiceInstaller.java | 25 +++
.../service/SystemServiceInstallerFactory.java | 28 ++++
.../brooklyn/entity/service/service.sh | 51 +++++++
.../service/SystemServiceEnricherTest.java | 95 ++++++++++++
7 files changed, 597 insertions(+)
----------------------------------------------------------------------