CLOUDSTACK-4736: Monitoring services in VR

This commit is contained in:
Jayapal 2013-11-05 23:19:22 +05:30
parent 80813375ae
commit b464a20a52
12 changed files with 822 additions and 35 deletions

View File

@ -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;
}
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -155,6 +155,7 @@
<bean id="externalPublicIpStatisticsDaoImpl" class="com.cloud.usage.dao.ExternalPublicIpStatisticsDaoImpl" /> <bean id="externalPublicIpStatisticsDaoImpl" class="com.cloud.usage.dao.ExternalPublicIpStatisticsDaoImpl" />
<bean id="firewallRulesCidrsDaoImpl" class="com.cloud.network.dao.FirewallRulesCidrsDaoImpl" /> <bean id="firewallRulesCidrsDaoImpl" class="com.cloud.network.dao.FirewallRulesCidrsDaoImpl" />
<bean id="firewallRulesDaoImpl" class="com.cloud.network.dao.FirewallRulesDaoImpl" /> <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="globalLoadBalancerDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerDaoImpl" />
<bean id="globalLoadBalancerLbRuleMapDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerLbRuleMapDaoImpl" /> <bean id="globalLoadBalancerLbRuleMapDaoImpl" class="org.apache.cloudstack.region.gslb.GlobalLoadBalancerLbRuleMapDaoImpl" />
<bean id="guestOSCategoryDaoImpl" class="com.cloud.storage.dao.GuestOSCategoryDaoImpl" /> <bean id="guestOSCategoryDaoImpl" class="com.cloud.storage.dao.GuestOSCategoryDaoImpl" />

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -118,34 +118,7 @@ import com.cloud.agent.api.check.CheckSshCommand;
import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand;
import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer; import com.cloud.agent.api.proxy.ConsoleProxyLoadAnswer;
import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand;
import com.cloud.agent.api.routing.CreateIpAliasCommand; import com.cloud.agent.api.routing.*;
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.storage.CopyVolumeAnswer; import com.cloud.agent.api.storage.CopyVolumeAnswer;
import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.CreateAnswer; import com.cloud.agent.api.storage.CreateAnswer;
@ -633,6 +606,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((ScaleVmCommand) cmd); return execute((ScaleVmCommand) cmd);
} else if (clazz == PvlanSetupCommand.class) { } else if (clazz == PvlanSetupCommand.class) {
return execute((PvlanSetupCommand) cmd); return execute((PvlanSetupCommand) cmd);
} else if (clazz == SetMonitorServiceCommand.class) {
return execute((SetMonitorServiceCommand) cmd);
} else { } else {
return Answer.createUnsupportedCommandAnswer(cmd); return Answer.createUnsupportedCommandAnswer(cmd);
} }
@ -8121,6 +8096,30 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return new Answer(cmd, success, ""); 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) { protected SetFirewallRulesAnswer execute(SetFirewallRulesCommand cmd) {
String[] results = new String[cmd.getRules().length]; String[] results = new String[cmd.getRules().length];
String callResult; String callResult;

View File

@ -41,6 +41,7 @@ import javax.ejb.Local;
import javax.inject.Inject; import javax.inject.Inject;
import javax.naming.ConfigurationException; import javax.naming.ConfigurationException;
import com.cloud.agent.api.to.*;
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd; import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.context.CallContext;
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; 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.RemoteAccessVpnCfgCommand;
import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SavePasswordCommand;
import com.cloud.agent.api.routing.SetFirewallRulesCommand; 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.SetPortForwardingRulesCommand;
import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand;
import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.routing.VmDataCommand;
import com.cloud.agent.api.routing.VpnUsersCfgCommand; 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.agent.manager.Commands;
import com.cloud.alert.AlertManager; import com.cloud.alert.AlertManager;
import com.cloud.cluster.ClusterManager; 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.LoadBalancerDao;
import com.cloud.network.dao.LoadBalancerVMMapDao; import com.cloud.network.dao.LoadBalancerVMMapDao;
import com.cloud.network.dao.LoadBalancerVO; import com.cloud.network.dao.LoadBalancerVO;
import com.cloud.network.dao.MonitoringServiceVO;
import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO; import com.cloud.network.dao.NetworkVO;
import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; 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.UserIpv6AddressDao;
import com.cloud.network.dao.VirtualRouterProviderDao; import com.cloud.network.dao.VirtualRouterProviderDao;
import com.cloud.network.dao.VpnUserDao; import com.cloud.network.dao.VpnUserDao;
import com.cloud.network.dao.MonitoringServiceDao;
import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule;
import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbDestination;
import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; 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.RedundantState;
import com.cloud.network.router.VirtualRouter.Role; import com.cloud.network.router.VirtualRouter.Role;
import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.FirewallRule;
import com.cloud.network.MonitoringService;
import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.FirewallRule.Purpose;
import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.rules.LoadBalancerContainer.Scheme;
import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PortForwardingRule;
@ -369,8 +368,11 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
IpAddressManager _ipAddrMgr; IpAddressManager _ipAddrMgr;
@Inject @Inject
ConfigDepot _configDepot; ConfigDepot _configDepot;
@Inject
MonitoringServiceDao _monitorServiceDao;
int _routerRamSize; int _routerRamSize;
int _routerCpuMHz; int _routerCpuMHz;
int _retry = 2; int _retry = 2;
@ -2332,10 +2334,56 @@ public class VirtualNetworkApplianceManagerImpl extends ManagerBase implements V
finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId); finalizeUserDataAndDhcpOnStart(cmds, router, provider, guestNetworkId);
} }
finalizeMonitorServiceOnStrat(cmds, router, provider, routerGuestNtwkIds.get(0));
return true; 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) { protected NicProfile getControlNic(VirtualMachineProfile profile) {
DomainRouterVO router = _routerDao.findById(profile.getId()); DomainRouterVO router = _routerDao.findById(profile.getId());
DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId());

View File

@ -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); 'Sets the attribute for uniquemembers within a group','uniquemember',NULL,NULL,0);
UPDATE `cloud`.`volumes` SET display_volume=1 where id>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);

View File

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

View File

@ -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()