private Entity getMasterNode() { return entity().getAttribute(BrooklynCluster.MASTER_NODE); } }
protected Location getLocation(@Nullable Collection<? extends Location> locations) { if (locations==null || locations.isEmpty()) locations = entity().getLocations(); if (locations.isEmpty()) { MachineProvisioningLocation<?> provisioner = entity().getAttribute(SoftwareProcess.PROVISIONING_LOCATION); if (provisioner!=null) locations = Arrays.<Location>asList(provisioner); } locations = Locations.getLocationsCheckingAncestors(locations, entity()); Maybe<MachineLocation> ml = Locations.findUniqueMachineLocation(locations); if (ml.isPresent()) return ml.get(); if (locations.isEmpty()) throw new IllegalArgumentException("No locations specified when starting "+entity()); if (locations.size() != 1 || Iterables.getOnlyElement(locations)==null) throw new IllegalArgumentException("Ambiguous locations detected when starting "+entity()+": "+locations); return Iterables.getOnlyElement(locations); }
@Override public void run() { String runDir = entity().getAttribute(SoftwareProcess.RUN_DIR); String bkDir = Urls.mergePaths(runDir, "..", Urls.getBasename(runDir)+"-backups", bkName); log.debug(this+" storing backup of previous version in "+bkDir); DynamicTasks.queue(SshEffectorTasks.ssh( "cd "+runDir, "mkdir -p "+bkDir, "mv * "+bkDir // By removing the run dir of the entity we force it to go through // the customize step again on start and re-generate local-brooklyn.properties. ).summary("move files")); } }).build());
private static void waitBrieflyForServiceUpIfStateIsRunning(Entity entity, Lifecycle state) { if (state==Lifecycle.RUNNING) { Boolean up = ((EntityInternal)entity).getAttribute(Attributes.SERVICE_UP); if (!Boolean.TRUE.equals(up) && !Boolean.TRUE.equals(Entities.isReadOnly(entity))) { // pause briefly to allow any recent problem-clearing processing to complete Stopwatch timer = Stopwatch.createStarted(); boolean nowUp = Repeater.create() .every(ValueResolver.REAL_QUICK_PERIOD) .limitTimeTo(ValueResolver.PRETTY_QUICK_WAIT) .until(entity, EntityPredicates.attributeEqualTo(Attributes.SERVICE_UP, true)) .run(); if (nowUp) { log.debug("Had to wait "+Duration.of(timer)+" for "+entity+" "+Attributes.SERVICE_UP+" to be true before setting "+state); } else { log.warn("Service is not up when setting "+state+" on "+entity+"; delayed "+Duration.of(timer)+" " + "but "+Attributes.SERVICE_UP+" did not recover from "+up+"; not-up-indicators="+entity.getAttribute(Attributes.SERVICE_NOT_UP_INDICATORS)); } } } }
MachineProvisioningLocation<MachineLocation> provisioner = entity().getAttribute(SoftwareProcess.PROVISIONING_LOCATION);
protected boolean tryStopWindowsService() { if (getWindowsServiceName()==null) return false; int result = DynamicTasks.queue(SshEffectorTasks.ssh("sc query \""+getWindowsServiceName()+"\"").runAsCommand()).get(); if (0==result) return true; if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING) return true; throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)"); }
protected boolean tryStopService() { if (getServiceName()==null) return false; int result = DynamicTasks.queue(SshEffectorTasks.ssh("/etc/init.d/"+getServiceName()+" stop").runAsRoot()).get(); if (0==result) return true; if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING) return true; throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)"); }
protected boolean tryStopWindowsService() { if (getWindowsServiceName()==null) return false; int result = DynamicTasks.queue(SshEffectorTasks.ssh("sc query \""+getWindowsServiceName()+"\"").runAsCommand()).get(); if (0==result) return true; if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING) return true; throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)"); }
protected boolean tryStopService() { if (getServiceName()==null) return false; int result = DynamicTasks.queue(SshEffectorTasks.ssh("/etc/init.d/"+getServiceName()+" stop").runAsRoot()).get(); if (0==result) return true; if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)!=Lifecycle.RUNNING) return true; throw new IllegalStateException("The process for "+entity()+" appears could not be stopped (exit code "+result+" to service stop)"); }
@Override public String call() { if (entity().getAttribute(SoftwareProcess.SERVICE_STATE_ACTUAL) == Lifecycle.STOPPED) { log.debug("Skipping stop of entity " + entity() + " when already stopped"); return "Already stopped"; } ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING); entity().sensors().set(SoftwareProcess.SERVICE_UP, false); preStopCustom(); return null; } }
@Override public Void call(ConfigBag parameters) { String newPass = Preconditions.checkNotNull(parameters.get(PASSWORD), "password is required"); String oldPass = entity().getAttribute(MySqlNode.PASSWORD); entity().sensors().set(MySqlNode.PASSWORD, newPass); MySqlDriver driver = ((MySqlNodeImpl)entity()).getDriver(); driver.changePassword(oldPass, newPass); SshMachineLocation machine = EffectorTasks.getSshMachine(entity()); DynamicTasks.queue( SshTasks.newSshExecTaskFactory(machine, "cd "+entity().getAttribute(MySqlNode.RUN_DIR), "sed -i'' -e 's@^\\(\\s*password\\s*=\\s*\\).*$@\\1" + newPass.replace("\\", "\\\\") + "@g' mymysql.cnf") .requiringExitCodeZero() .summary("Change root password")); return null; } }
protected boolean tryStopPid() { Integer pid = entity().getAttribute(Attributes.PID); if (pid==null) { if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)==Lifecycle.RUNNING && getPidFile()==null) log.warn("No PID recorded for "+entity()+" when running, with PID file "+getPidFile()+"; skipping kill in "+Tasks.current()); else if (log.isDebugEnabled()) log.debug("No PID recorded for "+entity()+"; skipping ("+entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)+" / "+getPidFile()+")"); return false; } // allow non-zero exit as process may have already been killed DynamicTasks.queue(SshEffectorTasks.ssh( "kill "+pid, "sleep 5", BashCommands.ok("kill -9 "+pid)).allowingNonZeroExitCode().runAsRoot()).block(); if (DynamicTasks.queue(SshEffectorTasks.isPidRunning(pid).runAsRoot()).get()) { throw new IllegalStateException("Process for "+entity()+" in "+pid+" still running after kill"); } entity().sensors().set(Attributes.PID, null); return true; }
protected boolean tryStopPid() { Integer pid = entity().getAttribute(Attributes.PID); if (pid==null) { if (entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)==Lifecycle.RUNNING && getPidFile()==null) log.warn("No PID recorded for "+entity()+" when running, with PID file "+getPidFile()+"; skipping kill in "+Tasks.current()); else if (log.isDebugEnabled()) log.debug("No PID recorded for "+entity()+"; skipping ("+entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL)+" / "+getPidFile()+")"); return false; } // allow non-zero exit as process may have already been killed DynamicTasks.queue(SshEffectorTasks.ssh( "kill "+pid, "sleep 5", BashCommands.ok("kill -9 "+pid)).allowingNonZeroExitCode().runAsRoot()).block(); if (DynamicTasks.queue(SshEffectorTasks.isPidRunning(pid).runAsRoot()).get()) { throw new IllegalStateException("Process for "+entity()+" in "+pid+" still running after kill"); } entity().sensors().set(Attributes.PID, null); return true; }
@Test public void testRemoveSensorThroughEntity() throws Exception{ entity.sensors().set(TEST_SENSOR, "abc"); entity.removeAttribute(TEST_SENSOR); assertFalse(entity.getEntityType().getSensors().contains(TEST_SENSOR), "sensors="+entity.getEntityType().getSensors()); assertEquals(entity.getAttribute(TEST_SENSOR), null); assertEventuallyListenerEventsEqual(ImmutableList.of(BasicSensorEvent.ofUnchecked(SENSOR_ADDED, entity, TEST_SENSOR), BasicSensorEvent.ofUnchecked(SENSOR_REMOVED, entity, TEST_SENSOR))); }
private void selectMaster(ConfigBag parameters) { String newMasterId = parameters.get(NEW_MASTER_ID); Preconditions.checkNotNull(newMasterId, NEW_MASTER_ID.getName() + " parameter is required"); final Entity oldMaster = entity().getAttribute(BrooklynCluster.MASTER_NODE); if (oldMaster != null && oldMaster.getId().equals(newMasterId)) { LOG.info(newMasterId + " is already the current master, no change needed."); return; } final Entity newMaster = getMember(newMasterId); //1. Increase the priority of the node we wish to become master toggleNodePriority(newMaster, HA_MASTER_PRIORITY); //2. Demote the existing master so a new election takes place try { // this allows the finally block to run even on failure DynamicTasks.swallowChildrenFailures(); if (oldMaster != null) { demoteOldMaster(oldMaster, HighAvailabilityMode.HOT_STANDBY); } waitMasterHandover(oldMaster, newMaster); } finally { //3. Revert the priority of the node once it has become master toggleNodePriority(newMaster, HA_STANDBY_PRIORITY); } checkMasterSelected(newMaster); }
@Test public void testCreatePasswordCreatesAPasswordOfDefaultLength() { final CreatePasswordSensor sensor = new CreatePasswordSensor(ConfigBag.newInstance() .configure(CreatePasswordSensor.SENSOR_NAME, SENSOR_STRING.getName())); sensor.apply(entity); String password = entity.getAttribute(SENSOR_STRING); Asserts.assertEquals(password.length(), 12); } }
protected void markTransitioningEntityOnFireOnRebind(EntityInternal entity, Lifecycle expectedState) { LOG.warn("Entity {} being marked as on-fire because it was in state {} on rebind; indicators={}", new Object[] {entity, expectedState, entity.getAttribute(Attributes.SERVICE_NOT_UP_INDICATORS)}); ServiceStateLogic.setExpectedState(entity, Lifecycle.ON_FIRE); ServiceStateLogic.ServiceNotUpLogic.updateNotUpIndicator(
MachineProvisioningLocation<MachineLocation> provisioner = entity().getAttribute(SoftwareProcess.PROVISIONING_LOCATION);
@Override public Void call(ConfigBag parameters) { MutableMap<String, String> formParams = MutableMap.of(); Lifecycle initialState = entity().getAttribute(Attributes.SERVICE_STATE_ACTUAL); ServiceStateLogic.setExpectedState(entity(), Lifecycle.STOPPING); for (ConfigKey<?> k: new ConfigKey<?>[] { STOP_APPS_FIRST, FORCE_SHUTDOWN_ON_ERROR, SHUTDOWN_TIMEOUT, REQUEST_TIMEOUT, DELAY_FOR_HTTP_RETURN }) formParams.addIfNotNull(k.getName(), toNullableString(parameters.get(k))); try { log.debug("Shutting down "+entity()+" with "+formParams); HttpToolResponse resp = ((BrooklynNode)entity()).http() .post("/v1/server/shutdown", ImmutableMap.of("Brooklyn-Allow-Non-Master-Access", "true"), formParams); if (resp.getResponseCode() != HttpStatus.SC_NO_CONTENT) { throw new IllegalStateException("Response code "+resp.getResponseCode()); } } catch (Exception e) { Exceptions.propagateIfFatal(e); throw new PropagatedRuntimeException("Error shutting down remote node "+entity()+" (in state "+initialState+"): "+Exceptions.collapseText(e), e); } ServiceNotUpLogic.updateNotUpIndicator(entity(), SHUTDOWN.getName(), "Shutdown of remote node has completed successfuly"); return null; }
@Override protected String stopProcessesAtMachine() { // TODO Where is best place to set? // Really should set this with a Feed that checks pid periodically. entity().sensors().set(Attributes.SERVICE_UP, false); Integer pid = entity().getAttribute(Attributes.PID); if (pid==null) { log.info("mysql not running"); return "No pid -- is it running?"; } DynamicTasks.queue(SshEffectorTasks.ssh( "cd "+dir(entity)+"/*", "./support-files/mysql.server stop" ).summary("stop mysql")); return "submitted stop"; } }.attachLifecycleEffectors(entity);