Search in sources :

Example 1 with PersisterException

use of com.mesosphere.sdk.storage.PersisterException in project dcos-commons by mesosphere.

the class CuratorPersisterTest method testAclBehavior.

// Uses a real ZK instance to ensure that our integration works as expected:
@Test
public void testAclBehavior() throws Exception {
    CuratorTestUtils.clear(testZk);
    when(mockServiceSpec.getZookeeperConnection()).thenReturn(testZk.getConnectString());
    Persister nonAclPersister = CuratorPersister.newBuilder(mockServiceSpec).build();
    Persister aclPersister = CuratorPersister.newBuilder(mockServiceSpec).setCredentials("testuser", "testpw").build();
    // Store value with ACL.
    aclPersister.set(PATH_1, DATA_1);
    // Readable with appropriate Auth and ACL.
    assertArrayEquals(DATA_1, aclPersister.get(PATH_1));
    // Readable with world:anyone permission.
    assertArrayEquals(DATA_1, nonAclPersister.get(PATH_1));
    // Not overwriteable with world:anyone permission.
    try {
        nonAclPersister.set(PATH_1, DATA_2);
        fail("Should have failed with auth exception");
    } catch (PersisterException e) {
        assertEquals(Reason.STORAGE_ERROR, e.getReason());
        assertTrue(e.getCause() instanceof KeeperException.NoAuthException);
    }
    // Not overwriteable with incorrect Auth
    try {
        Persister wrongAclPersister = CuratorPersister.newBuilder(mockServiceSpec).setCredentials("testuser", "otherpw").build();
        wrongAclPersister.set(PATH_1, DATA_SUB_1);
        fail("Should have failed with auth exception");
    } catch (PersisterException e) {
        assertEquals(Reason.STORAGE_ERROR, e.getReason());
        assertTrue(e.getCause() instanceof KeeperException.NoAuthException);
    }
    // Delete ACL'ed data so that other tests don't have ACL problems trying to clear it:
    aclPersister.recursiveDelete(PATH_PARENT);
}
Also used : PersisterException(com.mesosphere.sdk.storage.PersisterException) Persister(com.mesosphere.sdk.storage.Persister)

Example 2 with PersisterException

use of com.mesosphere.sdk.storage.PersisterException in project dcos-commons by mesosphere.

the class CuratorPersister method recursiveDelete.

@Override
public void recursiveDelete(String unprefixedPath) throws PersisterException {
    final String path = withFrameworkPrefix(unprefixedPath);
    if (path.equals(serviceRootPath)) {
        // Special case: If we're being told to delete root, we should instead delete the contents OF root. We don't
        // have access to delete the root-level '/dcos-service-<svcname>' node itself, despite having created it.
        /* Effective 5/8/2017:
             * We cannot delete the root node of a service directly.
             * This is due to the ACLs on the global DC/OS ZK.
             *
             * The root has:
             * [zk: localhost:2181(CONNECTED) 1] getAcl /
             * 'world,'anyone
             * : cr
             * 'ip,'127.0.0.1
             * : cdrwa
             *
             * Our service nodes have:
             * [zk: localhost:2181(CONNECTED) 0] getAcl /dcos-service-hello-world
             * 'world,'anyone
             * : cdrwa
             *
             * The best we can do is to wipe everything under the root node. A proposed way to "fix" things
             * lives at https://jira.mesosphere.com/browse/INFINITY-1470.
             */
        LOGGER.debug("Deleting children of root {}", path);
        try {
            CuratorTransactionFinal transaction = client.inTransaction().check().forPath(serviceRootPath).and();
            Set<String> pendingDeletePaths = new HashSet<>();
            for (String child : client.getChildren().forPath(serviceRootPath)) {
                // Custom logic for root-level children: don't delete the lock node
                if (child.equals(CuratorLocker.LOCK_PATH_NAME)) {
                    continue;
                }
                String childPath = PersisterUtils.join(serviceRootPath, child);
                transaction = deleteChildrenOf(client, childPath, transaction, pendingDeletePaths).delete().forPath(childPath).and();
            }
            transaction.commit();
        } catch (Exception e) {
            throw new PersisterException(Reason.STORAGE_ERROR, String.format("Unable to delete children of root %s: %s", path, e.getMessage()), e);
        }
        // Need to explicitly set null or else curator will return a zero-bytes value later:
        set(unprefixedPath, null);
    } else {
        // Normal case: Delete node itself and any/all children.
        LOGGER.debug("Deleting {} (and any children)", path);
        try {
            client.delete().deletingChildrenIfNeeded().forPath(path);
        } catch (KeeperException.NoNodeException e) {
            throw new PersisterException(Reason.NOT_FOUND, String.format("Path to delete does not exist: %s", path), e);
        } catch (Exception e) {
            throw new PersisterException(Reason.STORAGE_ERROR, String.format("Unable to delete %s", path), e);
        }
    }
}
Also used : CuratorTransactionFinal(org.apache.curator.framework.api.transaction.CuratorTransactionFinal) PersisterException(com.mesosphere.sdk.storage.PersisterException) KeeperException(org.apache.zookeeper.KeeperException) PersisterException(com.mesosphere.sdk.storage.PersisterException) KeeperException(org.apache.zookeeper.KeeperException)

Example 3 with PersisterException

use of com.mesosphere.sdk.storage.PersisterException in project dcos-commons by mesosphere.

the class CuratorPersister method getMany.

@Override
public Map<String, byte[]> getMany(Collection<String> unprefixedPaths) throws PersisterException {
    if (unprefixedPaths.isEmpty()) {
        return Collections.emptyMap();
    }
    LOGGER.debug("Getting {} entries: {}", unprefixedPaths.size(), unprefixedPaths);
    Map<String, byte[]> result = new TreeMap<>();
    // changes, then it may make sense to look into some form of proper read locking here.
    for (String unprefixedPath : unprefixedPaths) {
        String path = withFrameworkPrefix(unprefixedPath);
        try {
            result.put(unprefixedPath, client.getData().forPath(path));
        } catch (KeeperException.NoNodeException e) {
            result.put(unprefixedPath, null);
        } catch (Exception e) {
            throw new PersisterException(Reason.STORAGE_ERROR, String.format("Unable to retrieve data from %s", path), e);
        }
    }
    return result;
}
Also used : PersisterException(com.mesosphere.sdk.storage.PersisterException) KeeperException(org.apache.zookeeper.KeeperException) KeeperException(org.apache.zookeeper.KeeperException) PersisterException(com.mesosphere.sdk.storage.PersisterException)

Example 4 with PersisterException

use of com.mesosphere.sdk.storage.PersisterException in project dcos-commons by mesosphere.

the class StateQueries method refreshCache.

/**
 * Refreshes the state store cache to reflect current data on ZK. Should only be needed if ZK was edited behind the
 * scheduler's back, or if there's a bug in the cache handling.
 */
public static Response refreshCache(StateStore stateStore) {
    PersisterCache cache = getPersisterCache(stateStore);
    if (cache == null) {
        LOGGER.warn("State store is not cached: Refresh is not applicable");
        return Response.status(Response.Status.CONFLICT).build();
    }
    try {
        LOGGER.info("Refreshing state store cache...");
        LOGGER.info("Before:\n- tasks: {}\n- properties: {}", stateStore.fetchTaskNames(), stateStore.fetchPropertyKeys());
        cache.refresh();
        LOGGER.info("After:\n- tasks: {}\n- properties: {}", stateStore.fetchTaskNames(), stateStore.fetchPropertyKeys());
        return ResponseUtils.jsonOkResponse(getCommandResult("refresh"));
    } catch (PersisterException ex) {
        LOGGER.error("Failed to refresh state cache", ex);
        return Response.serverError().build();
    }
}
Also used : PersisterCache(com.mesosphere.sdk.storage.PersisterCache) PersisterException(com.mesosphere.sdk.storage.PersisterException)

Example 5 with PersisterException

use of com.mesosphere.sdk.storage.PersisterException in project dcos-commons by mesosphere.

the class SchedulerRunner method run.

/**
 * Runs the scheduler. Don't forget to call this!
 * This should never exit, instead the entire process will be terminated internally.
 */
@Override
public void run() {
    SchedulerConfig schedulerConfig = schedulerBuilder.getSchedulerConfig();
    ServiceSpec serviceSpec = schedulerBuilder.getServiceSpec();
    Persister persister = schedulerBuilder.getPersister();
    // Get a curator lock, then check the schema version:
    CuratorLocker.lock(serviceSpec.getName(), serviceSpec.getZookeeperConnection());
    // Check and/or initialize schema version before doing any other storage access:
    new SchemaVersionStore(persister).check(SUPPORTED_SCHEMA_VERSION_SINGLE_SERVICE);
    Metrics.configureStatsd(schedulerConfig);
    AbstractScheduler scheduler = schedulerBuilder.build();
    scheduler.start();
    Optional<Scheduler> mesosScheduler = scheduler.getMesosScheduler();
    if (mesosScheduler.isPresent()) {
        ApiServer apiServer = new ApiServer(schedulerConfig, scheduler.getResources());
        apiServer.start(new AbstractLifeCycle.AbstractLifeCycleListener() {

            @Override
            public void lifeCycleStarted(LifeCycle event) {
                scheduler.markApiServerStarted();
            }
        });
        runScheduler(new FrameworkRunner(FrameworkConfig.fromServiceSpec(serviceSpec), PodSpecsCannotUseUnsupportedFeatures.serviceRequestsGpuResources(serviceSpec), schedulerBuilder.isRegionAwarenessEnabled()).getFrameworkInfo(new FrameworkStore(schedulerBuilder.getPersister()).fetchFrameworkId()), mesosScheduler.get(), schedulerBuilder.getServiceSpec(), schedulerBuilder.getSchedulerConfig());
    } else {
        /**
         * If no MesosScheduler is provided this scheduler has been deregistered and should report itself healthy
         * and provide an empty COMPLETE deploy plan so it may complete its UNINSTALL.
         *
         * See {@link UninstallScheduler#getMesosScheduler()}.
         */
        Plan emptyDeployPlan = new Plan() {

            @Override
            public List<Phase> getChildren() {
                return Collections.emptyList();
            }

            @Override
            public Strategy<Phase> getStrategy() {
                return new SerialStrategy<>();
            }

            @Override
            public UUID getId() {
                return UUID.randomUUID();
            }

            @Override
            public String getName() {
                return Constants.DEPLOY_PLAN_NAME;
            }

            @Override
            public List<String> getErrors() {
                return Collections.emptyList();
            }
        };
        try {
            PersisterUtils.clearAllData(persister);
        } catch (PersisterException e) {
            // Best effort.
            LOGGER.error("Failed to clear all data", e);
        }
        ApiServer apiServer = new ApiServer(schedulerConfig, Arrays.asList(new PlansResource(Collections.singletonList(DefaultPlanManager.createProceeding(emptyDeployPlan))), new HealthResource(Collections.emptyList())));
        apiServer.start(new AbstractLifeCycle.AbstractLifeCycleListener() {

            @Override
            public void lifeCycleStarted(LifeCycle event) {
                LOGGER.info("Started trivially healthy API server.");
            }
        });
    }
}
Also used : LifeCycle(org.eclipse.jetty.util.component.LifeCycle) AbstractLifeCycle(org.eclipse.jetty.util.component.AbstractLifeCycle) SchemaVersionStore(com.mesosphere.sdk.state.SchemaVersionStore) Phase(com.mesosphere.sdk.scheduler.plan.Phase) ApiServer(com.mesosphere.sdk.framework.ApiServer) Scheduler(org.apache.mesos.Scheduler) FrameworkRunner(com.mesosphere.sdk.framework.FrameworkRunner) PlansResource(com.mesosphere.sdk.http.endpoints.PlansResource) DefaultServiceSpec(com.mesosphere.sdk.specification.DefaultServiceSpec) ServiceSpec(com.mesosphere.sdk.specification.ServiceSpec) RawServiceSpec(com.mesosphere.sdk.specification.yaml.RawServiceSpec) PersisterException(com.mesosphere.sdk.storage.PersisterException) Plan(com.mesosphere.sdk.scheduler.plan.Plan) SerialStrategy(com.mesosphere.sdk.scheduler.plan.strategy.SerialStrategy) Persister(com.mesosphere.sdk.storage.Persister) AbstractLifeCycle(org.eclipse.jetty.util.component.AbstractLifeCycle) FrameworkStore(com.mesosphere.sdk.state.FrameworkStore) HealthResource(com.mesosphere.sdk.http.endpoints.HealthResource)

Aggregations

PersisterException (com.mesosphere.sdk.storage.PersisterException)7 KeeperException (org.apache.zookeeper.KeeperException)3 Persister (com.mesosphere.sdk.storage.Persister)2 ApiServer (com.mesosphere.sdk.framework.ApiServer)1 FrameworkRunner (com.mesosphere.sdk.framework.FrameworkRunner)1 HealthResource (com.mesosphere.sdk.http.endpoints.HealthResource)1 PlansResource (com.mesosphere.sdk.http.endpoints.PlansResource)1 Phase (com.mesosphere.sdk.scheduler.plan.Phase)1 Plan (com.mesosphere.sdk.scheduler.plan.Plan)1 SerialStrategy (com.mesosphere.sdk.scheduler.plan.strategy.SerialStrategy)1 DefaultServiceSpec (com.mesosphere.sdk.specification.DefaultServiceSpec)1 ServiceSpec (com.mesosphere.sdk.specification.ServiceSpec)1 RawServiceSpec (com.mesosphere.sdk.specification.yaml.RawServiceSpec)1 FrameworkStore (com.mesosphere.sdk.state.FrameworkStore)1 SchemaVersionStore (com.mesosphere.sdk.state.SchemaVersionStore)1 PersisterCache (com.mesosphere.sdk.storage.PersisterCache)1 CuratorTransactionFinal (org.apache.curator.framework.api.transaction.CuratorTransactionFinal)1 Scheduler (org.apache.mesos.Scheduler)1 AbstractLifeCycle (org.eclipse.jetty.util.component.AbstractLifeCycle)1 LifeCycle (org.eclipse.jetty.util.component.LifeCycle)1