You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ja...@apache.org on 2013/11/05 19:10:13 UTC
git commit: updated refs/heads/master to b464a20
Updated Branches:
refs/heads/master 80813375a -> b464a20a5
CLOUDSTACK-4736: Monitoring services in VR
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b464a20a
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b464a20a
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b464a20a
Branch: refs/heads/master
Commit: b464a20a5264f043cdeb306cc8ebace608ded6c8
Parents: 8081337
Author: Jayapal <ja...@apache.org>
Authored: Tue Nov 5 23:19:22 2013 +0530
Committer: Jayapal <ja...@apache.org>
Committed: Tue Nov 5 23:39:33 2013 +0530
----------------------------------------------------------------------
.../cloud/agent/api/to/MonitorServiceTO.java | 74 ++++++
.../com/cloud/network/MonitoringService.java | 42 +++
.../api/routing/SetMonitorServiceCommand.java | 56 ++++
.../spring-engine-schema-core-daos-context.xml | 1 +
.../cloud/network/dao/MonitoringServiceDao.java | 31 +++
.../network/dao/MonitoringServiceDaoImpl.java | 68 +++++
.../cloud/network/dao/MonitoringServiceVO.java | 119 +++++++++
.../xen/resource/CitrixResourceBase.java | 55 ++--
.../VirtualNetworkApplianceManagerImpl.java | 62 ++++-
setup/db/db/schema-421to430.sql | 15 ++
.../config/opt/cloud/bin/monitor_service.sh | 71 +++++
.../debian/config/root/monitorServices.py | 263 +++++++++++++++++++
12 files changed, 822 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/MonitorServiceTO.java b/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
new file mode 100644
index 0000000..deced16
--- /dev/null
+++ b/api/src/com/cloud/agent/api/to/MonitorServiceTO.java
@@ -0,0 +1,74 @@
+// 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 com.cloud.agent.api.to;
+
+import org.apache.cloudstack.api.InternalIdentity;
+
+public class MonitorServiceTO implements InternalIdentity {
+ long id;
+ String service;
+ String processname;
+ String serviceName;
+ String servicePath;
+ String pidFile;
+ boolean isDefault;
+
+ protected MonitorServiceTO() {
+ }
+
+ public MonitorServiceTO (String service, String processname, String serviceName, String servicepath, String pidFile, boolean isDefault) {
+ this.service = service;
+ this.processname = processname;
+ this.serviceName = serviceName;
+ this.servicePath = servicepath;
+ this.pidFile = pidFile;
+ this.isDefault = isDefault;
+ }
+
+
+
+ public boolean isDefault() {
+ return isDefault;
+ }
+
+ public String getPidFile() {
+ return pidFile;
+ }
+
+ @Override
+ public long getId() {
+ return id;
+ }
+
+
+ public String getService() {
+ return service;
+ }
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public String getServicePath() {
+ return servicePath;
+ }
+
+ public String getProcessname() {
+ return processname;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/api/src/com/cloud/network/MonitoringService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/MonitoringService.java b/api/src/com/cloud/network/MonitoringService.java
new file mode 100644
index 0000000..2a1754a
--- /dev/null
+++ b/api/src/com/cloud/network/MonitoringService.java
@@ -0,0 +1,42 @@
+// 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 com.cloud.network;
+import org.apache.cloudstack.acl.ControlledEntity;
+import org.apache.cloudstack.api.Identity;
+import org.apache.cloudstack.api.InternalIdentity;
+
+
+/**
+ * Nic represents one nic on the VM.
+ */
+public interface MonitoringService extends ControlledEntity, Identity, InternalIdentity {
+ /**
+ * @return id in the CloudStack database
+ */
+ enum Service {
+ Dhcp,
+ LoadBalancing,
+ Ssh,
+ Webserver,
+ }
+ long getId();
+ String getService();
+ String getServiceName();
+ String getPidFile();
+ String getServicePath();
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java b/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
new file mode 100644
index 0000000..109daf2
--- /dev/null
+++ b/core/src/com/cloud/agent/api/routing/SetMonitorServiceCommand.java
@@ -0,0 +1,56 @@
+// 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 com.cloud.agent.api.routing;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import com.cloud.agent.api.to.MonitorServiceTO;
+
+/**
+ *
+ * AccessDetails allow different components to put in information about
+ * how to access the components inside the command.
+ */
+public class SetMonitorServiceCommand extends NetworkElementCommand {
+ MonitorServiceTO[] services;
+
+ protected SetMonitorServiceCommand() {
+ }
+
+ public SetMonitorServiceCommand(List<MonitorServiceTO> services) {
+ this.services = services.toArray(new MonitorServiceTO[services.size()]);
+ }
+
+ public MonitorServiceTO[] getRules() {
+ return services;
+ }
+
+ public String getConfiguration() {
+
+ StringBuilder sb = new StringBuilder();
+ for (MonitorServiceTO service: services) {
+ sb.append("[").append(service.getService()).append("]").append(":");
+ sb.append("processname=").append(service.getProcessname()).append(":");
+ sb.append("servicename=").append(service.getServiceName()).append(":");
+ sb.append("pidfile=").append(service.getPidFile()).append(":");
+ sb.append(",");
+ }
+
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
----------------------------------------------------------------------
diff --git a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
index e811cce..98ef018 100644
--- a/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
+++ b/engine/schema/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml
@@ -155,6 +155,7 @@
<bean id="externalPublicIpStatisticsDaoImpl" class="com.cloud.usage.dao.ExternalPublicIpStatisticsDaoImpl" />
<bean id="firewallRulesCidrsDaoImpl" class="com.cloud.network.dao.FirewallRulesCidrsDaoImpl" />
<bean id="firewallRulesDaoImpl" class="com.cloud.network.dao.FirewallRulesDaoImpl" />
+ <bean id="MonitoringServiceDaoImpl" class="com.cloud.network.dao.MonitoringServiceDaoImpl" />
<bean id="globalLoadBalancerDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerDaoImpl" />
<bean id="globalLoadBalancerLbRuleMapDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerLbRuleMapDaoImpl" />
<bean id="guestOSCategoryDaoImpl" class="com.cloud.storage.dao.GuestOSCategoryDaoImpl" />
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
new file mode 100644
index 0000000..7cc7cc0
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDao.java
@@ -0,0 +1,31 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.utils.db.GenericDao;
+
+import java.util.List;
+
+public interface MonitoringServiceDao extends GenericDao<MonitoringServiceVO, Long> {
+
+ List<MonitoringServiceVO> listAllServices();
+ List<MonitoringServiceVO> listDefaultServices(boolean isDefault);
+
+ MonitoringServiceVO getServiceByName(String service);
+
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
new file mode 100644
index 0000000..53dc7d4
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceDaoImpl.java
@@ -0,0 +1,68 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import org.springframework.stereotype.Component;
+
+import javax.ejb.Local;
+import java.util.List;
+
+@Component
+@Local(value=MonitoringServiceDao.class)
+public class MonitoringServiceDaoImpl extends GenericDaoBase<MonitoringServiceVO, Long> implements MonitoringServiceDao {
+ private final SearchBuilder<MonitoringServiceVO> AllFieldsSearch;
+
+ public MonitoringServiceDaoImpl() {
+ super();
+ AllFieldsSearch = createSearchBuilder();
+ AllFieldsSearch.and("isDefault", AllFieldsSearch.entity().getDefault(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("service", AllFieldsSearch.entity().getService(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("processname", AllFieldsSearch.entity().getProcessname(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("servicename", AllFieldsSearch.entity().getServiceName(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("servicepath", AllFieldsSearch.entity().getServicePath(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("servicePidFile", AllFieldsSearch.entity().getPidFile(), SearchCriteria.Op.EQ);
+
+ AllFieldsSearch.done();
+ }
+
+
+
+ @Override
+ public List<MonitoringServiceVO> listAllServices() {
+ return null;
+ }
+
+ @Override
+ public List<MonitoringServiceVO> listDefaultServices(boolean isDefault) {
+ SearchCriteria<MonitoringServiceVO> sc = AllFieldsSearch.create();
+ sc.setParameters("isDefault", isDefault);
+ return listBy(sc);
+ }
+
+ @Override
+ public MonitoringServiceVO getServiceByName(String service) {
+ SearchCriteria<MonitoringServiceVO> sc = AllFieldsSearch.create();
+ sc.setParameters("service", service);
+ return findOneBy(sc);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
new file mode 100644
index 0000000..3f9122c
--- /dev/null
+++ b/engine/schema/src/com/cloud/network/dao/MonitoringServiceVO.java
@@ -0,0 +1,119 @@
+// 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 com.cloud.network.dao;
+
+import com.cloud.network.MonitoringService;
+
+import javax.persistence.*;
+import java.util.UUID;
+
+@Entity
+@Table(name = "monitoring_services")
+public class MonitoringServiceVO implements MonitoringService {
+
+ public MonitoringServiceVO(String service, String processname, String serviceName, String servicePath,
+ String pidFile) {
+ this.service = service;
+ this.processname = processname;
+ this.servicename = serviceName;
+ this.servicePath = servicePath;
+ this.servicePidFile= pidFile;
+
+ }
+
+ protected MonitoringServiceVO() {
+ }
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ long id;
+
+ @Column(name = "service")
+ String service;
+
+ @Column(name="process_name", updatable=false)
+ String processname;
+
+ @Column(name="service_name", updatable=false)
+ String servicename;
+
+ @Column(name="service_path", updatable=false)
+ private String servicePath;
+
+ @Column(name="pidFile", updatable=false)
+ private String servicePidFile;
+
+ @Column(name="isDefault")
+ private boolean isDefault;
+
+
+ @Column(name = "uuid")
+ String uuid = UUID.randomUUID().toString();
+
+ public long getId() {
+ return id;
+ }
+
+ @Override
+ public String getService() {
+ return this.service;
+ }
+
+ @Override
+ public String getServiceName() {
+ return this.servicename; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public String getPidFile() {
+ return this.servicePidFile;
+
+ }
+
+ @Override
+ public String getServicePath() {
+ return this.servicePidFile;
+ }
+
+ @Override
+ public String getUuid() {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public long getAccountId() {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ @Override
+ public long getDomainId() {
+ return 0; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public boolean getDefault() {
+ return isDefault;
+ }
+
+ public void setDefault(boolean isDefault) {
+ isDefault = isDefault;
+ }
+
+ public String getProcessname() {
+ return processname;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 5c9f4e5..69b7c9e 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -118,34 +118,7 @@ import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
-import com.cloud.agent.api.routing.CreateIpAliasCommand;
-import com.cloud.agent.api.routing.DeleteIpAliasCommand;
-import com.cloud.agent.api.routing.DhcpEntryCommand;
-import com.cloud.agent.api.routing.DnsMasqConfigCommand;
-import com.cloud.agent.api.routing.IpAliasTO;
-import com.cloud.agent.api.routing.IpAssocAnswer;
-import com.cloud.agent.api.routing.IpAssocCommand;
-import com.cloud.agent.api.routing.IpAssocVpcCommand;
-import com.cloud.agent.api.routing.LoadBalancerConfigCommand;
-import com.cloud.agent.api.routing.NetworkElementCommand;
-import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
-import com.cloud.agent.api.routing.SavePasswordCommand;
-import com.cloud.agent.api.routing.SetFirewallRulesAnswer;
-import com.cloud.agent.api.routing.SetFirewallRulesCommand;
-import com.cloud.agent.api.routing.SetNetworkACLAnswer;
-import com.cloud.agent.api.routing.SetNetworkACLCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
-import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
-import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
-import com.cloud.agent.api.routing.SetSourceNatAnswer;
-import com.cloud.agent.api.routing.SetSourceNatCommand;
-import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
-import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
-import com.cloud.agent.api.routing.SetStaticRouteAnswer;
-import com.cloud.agent.api.routing.SetStaticRouteCommand;
-import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
-import com.cloud.agent.api.routing.VmDataCommand;
-import com.cloud.agent.api.routing.VpnUsersCfgCommand;
+import com.cloud.agent.api.routing.*;
import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateAnswer;
@@ -633,6 +606,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((ScaleVmCommand) cmd);
} else if (clazz == PvlanSetupCommand.class) {
return execute((PvlanSetupCommand) cmd);
+ } else if (clazz == SetMonitorServiceCommand.class) {
+ return execute((SetMonitorServiceCommand) cmd);
} else {
return Answer.createUnsupportedCommandAnswer(cmd);
}
@@ -8121,6 +8096,30 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return new Answer(cmd, success, "");
}
+ private Answer execute(SetMonitorServiceCommand cmd) {
+ boolean success = true;
+
+ String config = cmd.getConfiguration();
+
+ Connection conn = getConnection();
+ String routerIp = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+
+ if (routerIp == null) {
+ return new Answer(cmd);
+ }
+
+ String args = "monitor_service.sh " + routerIp;
+ args += " -c " + config;
+
+ String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
+ if (result == null || result.isEmpty()) {
+ return new Answer(cmd, false, "SetMonitorServiceCommand failed to create cfg file.");
+ }
+
+ return new Answer(cmd, success, "");
+
+ }
+
protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
String[] results = new String[cmd.getRules().length];
String callResult;
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index a93480b..9b35a4b 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -41,6 +41,7 @@ import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
+import com.cloud.agent.api.to.*;
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
@@ -82,17 +83,12 @@ import com.cloud.agent.api.routing.NetworkElementCommand;
import com.cloud.agent.api.routing.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetFirewallRulesCommand;
+import com.cloud.agent.api.routing.SetMonitorServiceCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand;
-import com.cloud.agent.api.to.DhcpTO;
-import com.cloud.agent.api.to.FirewallRuleTO;
-import com.cloud.agent.api.to.IpAddressTO;
-import com.cloud.agent.api.to.LoadBalancerTO;
-import com.cloud.agent.api.to.PortForwardingRuleTO;
-import com.cloud.agent.api.to.StaticNatRuleTO;
import com.cloud.agent.manager.Commands;
import com.cloud.alert.AlertManager;
import com.cloud.cluster.ClusterManager;
@@ -164,6 +160,7 @@ import com.cloud.network.dao.IPAddressVO;
import com.cloud.network.dao.LoadBalancerDao;
import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVO;
+import com.cloud.network.dao.MonitoringServiceVO;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao;
@@ -175,6 +172,7 @@ import com.cloud.network.dao.Site2SiteVpnGatewayDao;
import com.cloud.network.dao.UserIpv6AddressDao;
import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.dao.VpnUserDao;
+import com.cloud.network.dao.MonitoringServiceDao;
import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy;
@@ -183,6 +181,7 @@ import com.cloud.network.lb.LoadBalancingRulesManager;
import com.cloud.network.router.VirtualRouter.RedundantState;
import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.network.rules.FirewallRule;
+import com.cloud.network.MonitoringService;
import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.network.rules.PortForwardingRule;
@@ -369,8 +368,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
IpAddressManager _ipAddrMgr;
@Inject
ConfigDepot _configDepot;
+ @Inject
+ MonitoringServiceDao _monitorServiceDao;
+
+
-
int _routerRamSize;
int _routerCpuMHz;
int _retry = 2;
@@ -2332,10 +2334,56 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
}
+ finalizeMonitorServiceOnStrat(cmds, router, provider, routerGuestNtwkIds.get(0));
return true;
}
+ private void finalizeMonitorServiceOnStrat(Commands cmds, DomainRouterVO router, Provider provider, long networkId) {
+
+ NetworkVO network = _networkDao.findById(networkId);
+
+ s_logger.debug("Creating monitoring services on "+ router +" start...");
+
+
+ // get the list of sevices for this network to monitor
+ List <MonitoringServiceVO> services = new ArrayList<MonitoringServiceVO>();
+ if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dhcp, Provider.VirtualRouter) ||
+ _networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Dns, Provider.VirtualRouter)) {
+ MonitoringServiceVO dhcpService = _monitorServiceDao.getServiceByName(MonitoringService.Service.Dhcp.toString());
+ if (dhcpService != null) {
+ services.add(dhcpService);
+ }
+ }
+
+ if (_networkModel.isProviderSupportServiceInNetwork(network.getId(), Service.Lb, Provider.VirtualRouter)) {
+ MonitoringServiceVO lbService = _monitorServiceDao.getServiceByName(MonitoringService.Service.LoadBalancing.toString());
+ if (lbService != null) {
+ services.add(lbService);
+ }
+ }
+ List<MonitoringServiceVO> defaultServices = _monitorServiceDao.listDefaultServices(true);
+ services.addAll(defaultServices);
+
+ List<MonitorServiceTO> servicesTO = new ArrayList<MonitorServiceTO>();
+ for (MonitoringServiceVO service: services) {
+ MonitorServiceTO serviceTO = new MonitorServiceTO( service.getService(), service.getProcessname(), service.getServiceName(), service.getServicePath(),
+ service.getPidFile(), service.getDefault());
+ servicesTO.add(serviceTO);
+ }
+
+ SetMonitorServiceCommand command = new SetMonitorServiceCommand(servicesTO);
+ command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
+ command.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, getRouterIpInNetwork(networkId, router.getId()));
+ command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+
+ cmds.addCommand("monitor", command);
+ }
+
+
+
+
+
protected NicProfile getControlNic(VirtualMachineProfile profile) {
DomainRouterVO router = _routerDao.findById(profile.getId());
DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/setup/db/db/schema-421to430.sql
----------------------------------------------------------------------
diff --git a/setup/db/db/schema-421to430.sql b/setup/db/db/schema-421to430.sql
index 9fe56c0..26e4abf 100644
--- a/setup/db/db/schema-421to430.sql
+++ b/setup/db/db/schema-421to430.sql
@@ -561,3 +561,18 @@ INSERT IGNORE INTO `cloud`.`configuration` VALUES ('Advanced', 'DEFAULT', 'manag
'Sets the attribute for uniquemembers within a group','uniquemember',NULL,NULL,0);
UPDATE `cloud`.`volumes` SET display_volume=1 where id>0;
+
+create table `cloud`.`monitoring_services` (
+`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
+`uuid` varchar(40), `service` varchar(255) COMMENT 'Service name',
+`process_name` varchar(255) COMMENT 'running process name',
+`service_name` varchar(255) COMMENT 'exact name of the running service',
+`service_path` varchar(255) COMMENT 'path of the service in system',
+`pidfile` varchar(255) COMMENT 'path of the pid file of the service',
+`isDefault` boolean COMMENT 'Default service', PRIMARY KEY (`id`)
+);
+
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(1,'ssh','sshd', 'ssh','/etc/init.d/ssh','/var/run/sshd.pid',true);
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(2,'dhcp','dnsmasq','dnsmasq','/etc/init.d/dnsmasq','/var/run/dnsmasq/dnsmasq.pid',false);
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(3,'loadbalancing','haproxy','haproxy','/etc/init.d/haproxy','/var/run/haproxy.pid',false);
+insert into cloud.monitoring_services(id, service, process_name, service_name, service_path, pidfile, isDefault) values(4,'webserver','apache2','apache2','/etc/init.d/apache2','/var/run/apache2.pid', true);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
new file mode 100755
index 0000000..a2b789c
--- /dev/null
+++ b/systemvm/patches/debian/config/opt/cloud/bin/monitor_service.sh
@@ -0,0 +1,71 @@
+#!/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.
+
+source /root/func.sh
+
+lock="biglock"
+locked=$(getLockFile $lock)
+if [ "$locked" != "1" ]
+then
+ exit 1
+fi
+
+set -x
+usage() {
+ printf "Usage: %s: -c config string \n" $(basename $0) >&2
+}
+
+configFile='/etc/monitor.conf'
+
+create_config() {
+services=$1;
+services_list=$(echo $services | cut -d, -f1- --output-delimiter=" ");
+
+echo "#Monitor services config" >$configFile
+
+for s in $services_list
+do
+service=$(echo $s | cut -d: -f1);
+processname=$(echo $s | cut -d: -f2);
+service_name=$(echo $s | cut -d: -f3);
+pidfile=$(echo $s | cut -d: -f4);
+
+echo $service >> $configFile;
+echo $processname >> $configFile
+echo $service_name >> $configFile
+echo $pidfile >> $configFile
+
+
+
+done
+
+}
+
+config=$2
+
+#delete cron job before updating config file
+crontab -l | grep -v monitorServices.py | crontab -
+
+create_config $config
+
+#add cron job
+(crontab -l ; echo "*/3 * * * * python /root/monitorServices.py") | crontab -
+
+
+unlock_exit 0 $lock $locked
+
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b464a20a/systemvm/patches/debian/config/root/monitorServices.py
----------------------------------------------------------------------
diff --git a/systemvm/patches/debian/config/root/monitorServices.py b/systemvm/patches/debian/config/root/monitorServices.py
new file mode 100755
index 0000000..358c9dc
--- /dev/null
+++ b/systemvm/patches/debian/config/root/monitorServices.py
@@ -0,0 +1,263 @@
+#!/usr/bin/python
+# 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.
+
+
+
+
+__author__ = 'jayapalreddy'
+
+from ConfigParser import SafeConfigParser
+from subprocess import *
+from os import path
+import time
+
+monitor_log='/var/log/monitor.log'
+class StatusCodes:
+ SUCCESS = 0
+ FAILED = 1
+ INVALID_INP = 2
+ RUNNING = 3
+ STOPPED = 4
+ STARTING = 5
+
+class log:
+ INFO = 'INFO'
+ ALERT = 'ALERT'
+ CRIT = 'CRIT'
+ NOTIF = 'NOTIF'
+
+
+
+
+def getConfig( config_file_path = "/etc/monitor.conf" ):
+ process_dict = {}
+ parser = SafeConfigParser()
+ parser.read( config_file_path )
+
+ #print 'Read values:\n'
+
+ for section in parser.sections():
+ # print section
+ process_dict[section] = {}
+
+ for name, value in parser.items(section):
+ process_dict[section][name] = value
+# print ' %s = %r' % (name, value)
+
+ return process_dict
+
+def printd (msg):
+ return 0
+ print msg
+
+def raisealert(severity, msg, process_name=None):
+ #timeStr=str(time.ctime())
+ if process_name is not None:
+ log = '['+severity +']'+" " + '['+process_name+']' + " " + msg +"\n"
+ else:
+ log = '['+severity+']' + " " + msg +"\n"
+
+ msg = 'logger -t monit '+ log
+ pout = Popen(msg, shell=True, stdout=PIPE)
+
+
+ #f= open(monitor_log,'r+')
+ #f.seek(0, 2)
+ #f.write(str(log))
+ #f.close()
+
+
+def isPidMatchPidFile(pidfile, pids):
+
+ if pids is None or isinstance(pids,list) != True or len(pids) == 0:
+ print "Invalid Arguments"
+ return StatusCodes.FAILED
+ if not path.isfile(pidfile):
+ #It seems there is no pid file for this service
+ printd("The pid file "+pidfile+" is not there for this process")
+ return StatusCodes.FAILED
+
+ fd=None
+ try:
+ fd = open(pidfile,'r')
+ except:
+ printd("pid file: "+ pidfile +" open failed")
+ return StatusCodes.FAILED
+
+
+ inp = fd.read()
+ printd("file content "+str(inp))
+ printd(pids)
+ tocheck_pid = inp.strip()
+ for item in pids:
+ if str(tocheck_pid) == item.strip():
+ printd("pid file matched")
+ return StatusCodes.SUCCESS
+
+ fd.close()
+ return StatusCodes.FAILED
+
+
+
+def checkProcessStatus( process ):
+ process_name = process.get('processname')
+ service_name = process.get('servicename')
+ pidfile = process.get('pidfile')
+ #temp_out = None
+ restartFailed=0
+ pidFileMatched=1
+ cmd=''
+ if process_name is None:
+ print "\n Invalid Process Name"
+ return StatusCodes.INVALID_INP
+ else:
+ msg="checking the process " + process_name
+ printd(msg)
+ cmd = 'pidof ' + process_name
+ printd(cmd)
+ #cmd = 'service ' + process_name + ' status'
+ pout = Popen(cmd, shell=True, stdout=PIPE)
+ exitStatus = pout.wait()
+ temp_out = pout.communicate()[0]
+
+ #check there is only one pid or not
+ if exitStatus == 0:
+ msg="pids: " +temp_out;
+ printd(msg)
+ pids = temp_out.split(' ')
+
+ #there is more than one process so match the pid file
+ #if not matched set pidFileMatched=0
+ printd("Checking pid file")
+ if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS:
+ pidFileMatched = 1;
+ else:
+ pidFileMatched = 0;
+
+ printd(pidFileMatched)
+ if exitStatus == 0 and pidFileMatched == 1:
+ printd("The process is running ....")
+ return StatusCodes.RUNNING
+ else:
+ printd('exit status:'+str(exitStatus))
+ msg="The process " + process_name +" is not running trying recover "
+ printd(msg)
+ #Retry the process state for few seconds
+ for i in range(1,10):
+ pout = Popen(cmd, shell=True, stdout=PIPE)
+ exitStatus = pout.wait()
+ temp_out = pout.communicate()[0]
+
+ if i < 5: # this is just for trying few more times
+ if exitStatus == 0:
+ pids = temp_out.split(' ')
+
+ if isPidMatchPidFile(pidfile, pids) == StatusCodes.SUCCESS:
+ pidFileMatched = 1;
+ printd("pid file is matched ...")
+ raisealert(log.INFO, "The process detected as running", process_name)
+ break
+ else:
+ printd("pid file is not matched ...")
+ pidFileMatched = 0;
+ continue
+ time.sleep(1)
+ else:
+ msg="The process " +process_name+" is not running trying recover "
+ raisealert(log.INFO,process_name,msg)
+
+ if service_name == 'apache2':
+ # Killing apache2 process with this the main service will not start
+ for pid in pids:
+ cmd = 'kill -9 '+pid;
+ printd(cmd)
+ Popen(cmd, shell=True, stdout=PIPE)
+
+ cmd = 'service ' + service_name + ' restart'
+ try:
+ time.sleep(1)
+ return_val= check_call(cmd , shell=True)
+ except CalledProcessError:
+ restartFailed=1
+ msg="service "+ process_name +" restart failed"
+ printd(msg)
+ continue
+
+ if return_val == 0:
+ printd("The process" + process_name +" recovered successfully ")
+ msg="The process " +process_name+" is recovered successfully "
+ raisealert(log.ALERT,process_name,msg)
+
+ break;
+ else:
+ #retry restarting the process for few tries
+ printd("process restart failing trying again ....")
+ restartFailed=1
+ time.sleep(1)
+ continue
+ #for end here
+
+ if restartFailed == 1:
+ msg="The process %s recover failed ", process_name;
+ raisealert(log.ALERT,process_name,msg)
+
+ printd("Restart failed after number of retries")
+ return StatusCodes.STOPPED
+
+ return StatusCodes.RUNNING
+
+def raiseAlert( process_name ):
+ print "process name %s is raised "%process_name
+
+def monitProcess( processes_info ):
+ if len( processes_info ) == 0:
+ print "Invalid Input"
+ return StatusCodes.INVALID_INP
+ for process,properties in processes_info.items():
+ if checkProcessStatus( properties) != StatusCodes.RUNNING:
+ print "\n Process %s is not Running"%process
+
+
+def main():
+ '''
+ Step1 : Get Config
+ '''
+
+ printd("monitoring started")
+ temp_dict = getConfig()
+
+ '''
+ Step2: Get Previous Run Log
+ '''
+
+ '''
+ Step3: Monitor and Raise Alert
+ '''
+ #raisealert(log.INFO, 'Monit started')
+ monitProcess( temp_dict )
+
+
+if __name__ == "__main__":
+ main()
+
+
+
+
+
+
+