mesos-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Guangya Liu <gyliu...@gmail.com>
Subject Re: [1/2] mesos git commit: Added aufs provisioning backend.
Date Wed, 08 Jun 2016 12:15:48 GMT
The document is being tracked here
https://issues.apache.org/jira/browse/MESOS-5549

On Wed, Jun 8, 2016 at 7:29 PM, Neil Conway <neil.conway@gmail.com> wrote:

> Can you update the documentation for this change, please?
>
> Thanks,
> Neil
>
> On Tue, Jun 7, 2016 at 6:14 PM,  <jieyu@apache.org> wrote:
> > Repository: mesos
> > Updated Branches:
> >   refs/heads/master 90871a48f -> e5358ed1c
> >
> >
> > Added aufs provisioning backend.
> >
> > Review: https://reviews.apache.org/r/47396/
> >
> >
> > Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
> > Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e5358ed1
> > Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e5358ed1
> > Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e5358ed1
> >
> > Branch: refs/heads/master
> > Commit: e5358ed1c132923d5fa357d1e337e037d1f29c8a
> > Parents: ca09304
> > Author: Shuai Lin <linshuai2012@gmail.com>
> > Authored: Mon Jun 6 18:05:15 2016 -0700
> > Committer: Jie Yu <yujie.jay@gmail.com>
> > Committed: Tue Jun 7 09:14:22 2016 -0700
> >
> > ----------------------------------------------------------------------
> >  src/Makefile.am                                 |   2 +
> >  .../containerizer/mesos/provisioner/backend.cpp |   9 +
> >  .../mesos/provisioner/backends/aufs.cpp         | 227
> +++++++++++++++++++
> >  .../mesos/provisioner/backends/aufs.hpp         |  70 ++++++
> >  .../containerizer/provisioner_backend_tests.cpp |  51 +++++
> >  src/tests/environment.cpp                       |  13 ++
> >  6 files changed, 372 insertions(+)
> > ----------------------------------------------------------------------
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/Makefile.am
> > ----------------------------------------------------------------------
> > diff --git a/src/Makefile.am b/src/Makefile.am
> > index a08ea40..b02b901 100644
> > --- a/src/Makefile.am
> > +++ b/src/Makefile.am
> > @@ -1001,6 +1001,7 @@ MESOS_LINUX_FILES =
>                        \
> >    slave/containerizer/mesos/isolators/filesystem/shared.cpp            \
> >    slave/containerizer/mesos/isolators/namespaces/pid.cpp               \
> >    slave/containerizer/mesos/isolators/network/cni/cni.cpp              \
> > +  slave/containerizer/mesos/provisioner/backends/aufs.cpp              \
> >    slave/containerizer/mesos/provisioner/backends/bind.cpp              \
> >    slave/containerizer/mesos/provisioner/backends/overlay.cpp
> >
> > @@ -1024,6 +1025,7 @@ MESOS_LINUX_FILES +=
>                         \
> >    slave/containerizer/mesos/isolators/filesystem/shared.hpp            \
> >    slave/containerizer/mesos/isolators/namespaces/pid.hpp               \
> >    slave/containerizer/mesos/isolators/network/cni/cni.hpp              \
> > +  slave/containerizer/mesos/provisioner/backends/aufs.hpp              \
> >    slave/containerizer/mesos/provisioner/backends/bind.hpp              \
> >    slave/containerizer/mesos/provisioner/backends/overlay.hpp
> >
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/slave/containerizer/mesos/provisioner/backend.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/slave/containerizer/mesos/provisioner/backend.cpp
> b/src/slave/containerizer/mesos/provisioner/backend.cpp
> > index b2a20b7..93a2c3a 100644
> > --- a/src/slave/containerizer/mesos/provisioner/backend.cpp
> > +++ b/src/slave/containerizer/mesos/provisioner/backend.cpp
> > @@ -25,6 +25,7 @@
> >  #include "slave/containerizer/mesos/provisioner/backend.hpp"
> >
> >  #ifdef __linux__
> > +#include "slave/containerizer/mesos/provisioner/backends/aufs.hpp"
> >  #include "slave/containerizer/mesos/provisioner/backends/bind.hpp"
> >  #endif
> >  #include "slave/containerizer/mesos/provisioner/backends/copy.hpp"
> > @@ -47,6 +48,14 @@ hashmap<string, Owned<Backend>> Backend::create(const
> Flags& flags)
> >  #ifdef __linux__
> >    creators.put("bind", &BindBackend::create);
> >
> > +  Try<bool> aufsSupported = fs::aufs::supported();
> > +  if (aufsSupported.isError()) {
> > +    LOG(WARNING) << "Failed to check aufs availability: '"
> > +                 << aufsSupported.error();
> > +  } else if (aufsSupported.get()) {
> > +    creators.put("aufs", &AufsBackend::create);
> > +  }
> > +
> >    Try<bool> overlayfsSupported = fs::overlay::supported();
> >    if (overlayfsSupported.isError()) {
> >      LOG(WARNING) << "Failed to check overlayfs availability: '"
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/slave/containerizer/mesos/provisioner/backends/aufs.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/slave/containerizer/mesos/provisioner/backends/aufs.cpp
> b/src/slave/containerizer/mesos/provisioner/backends/aufs.cpp
> > new file mode 100644
> > index 0000000..54c0057
> > --- /dev/null
> > +++ b/src/slave/containerizer/mesos/provisioner/backends/aufs.cpp
> > @@ -0,0 +1,227 @@
> > +// 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.
> > +
> > +#include <process/dispatch.hpp>
> > +#include <process/process.hpp>
> > +
> > +#include <stout/adaptor.hpp>
> > +#include <stout/foreach.hpp>
> > +#include <stout/os.hpp>
> > +
> > +#include "linux/fs.hpp"
> > +
> > +#include "slave/containerizer/mesos/provisioner/backends/aufs.hpp"
> > +
> > +using process::Failure;
> > +using process::Future;
> > +using process::Owned;
> > +using process::Process;
> > +using process::Shared;
> > +
> > +using process::dispatch;
> > +using process::spawn;
> > +using process::wait;
> > +
> > +using std::string;
> > +using std::vector;
> > +
> > +namespace mesos {
> > +namespace internal {
> > +namespace slave {
> > +
> > +class AufsBackendProcess : public Process<AufsBackendProcess>
> > +{
> > +public:
> > +  Future<Nothing> provision(
> > +      const vector<string>& layers,
> > +      const string& rootfs,
> > +      const string& backendDir);
> > +
> > +  Future<bool> destroy(const string& rootfs);
> > +};
> > +
> > +
> > +Try<Owned<Backend>> AufsBackend::create(const Flags&)
> > +{
> > +  Result<string> user = os::user();
> > +  if (!user.isSome()) {
> > +    return Error(
> > +        "Failed to determine user: " +
> > +        (user.isError() ? user.error() : "username not found"));
> > +  }
> > +
> > +  if (user.get() != "root") {
> > +    return Error(
> > +      "AufsBackend requires root privileges, "
> > +      "but is running as user " + user.get());
> > +  }
> > +
> > +  return Owned<Backend>(new AufsBackend(
> > +      Owned<AufsBackendProcess>(new AufsBackendProcess())));
> > +}
> > +
> > +
> > +AufsBackend::~AufsBackend()
> > +{
> > +  terminate(process.get());
> > +  wait(process.get());
> > +}
> > +
> > +
> > +AufsBackend::AufsBackend(Owned<AufsBackendProcess> _process)
> > +  : process(_process)
> > +{
> > +  spawn(CHECK_NOTNULL(process.get()));
> > +}
> > +
> > +
> > +Future<Nothing> AufsBackend::provision(
> > +    const vector<string>& layers,
> > +    const string& rootfs,
> > +    const string& backendDir)
> > +{
> > +  return dispatch(
> > +      process.get(),
> > +      &AufsBackendProcess::provision,
> > +      layers,
> > +      rootfs,
> > +      backendDir);
> > +}
> > +
> > +Future<bool> AufsBackend::destroy(const string& rootfs)
> > +{
> > +  return dispatch(process.get(), &AufsBackendProcess::destroy, rootfs);
> > +}
> > +
> > +
> > +Future<Nothing> AufsBackendProcess::provision(
> > +    const vector<string>& layers,
> > +    const string& rootfs,
> > +    const string& backendDir)
> > +{
> > +  if (layers.size() == 0) {
> > +    return Failure("No filesystem layer provided");
> > +  }
> > +
> > +  Try<Nothing> mkdir = os::mkdir(rootfs);
> > +  if (mkdir.isError()) {
> > +    return Failure(
> > +        "Failed to create container rootfs at '" +
> > +        rootfs + "': " + mkdir.error());
> > +  }
> > +
> > +  const string scratchDirId = Path(rootfs).basename();
> > +  const string scratchDir = path::join(backendDir, "scratch",
> scratchDirId);
> > +
> > +  // The top writable directory for aufs.
> > +  const string workdir = path::join(scratchDir, "workdir");
> > +
> > +  mkdir = os::mkdir(workdir);
> > +  if (mkdir.isError()) {
> > +    return Failure(
> > +        "Failed to create aufs workdir at '" +
> > +        workdir + "': " + mkdir.error());
> > +  }
> > +
> > +  // See http://aufs.sourceforge.net/aufs2/man.html
> > +  // for the mount syntax for aufs.
> > +  string options = "dirs=" + workdir + ":";
> > +
> > +  // For aufs, the specified lower directories will be stacked
> > +  // beginning from the rightmost one and going left. But we need the
> > +  // first layer in the vector to be the bottom most layer.
> > +  options += strings::join(":", adaptor::reverse(layers));
> > +
> > +  VLOG(1) << "Provisioning image rootfs with aufs: '" << options <<
"'";
> > +
> > +  Try<Nothing> mount = fs::mount(
> > +      "aufs",
> > +      rootfs,
> > +      "aufs",
> > +      0,
> > +      options);
> > +
> > +  if (mount.isError()) {
> > +    return Failure(
> > +        "Failed to mount rootfs '" + rootfs +
> > +        "' with aufs: " + mount.error());
> > +  }
> > +
> > +  // Mark the mount as shared+slave.
> > +  mount = fs::mount(
> > +      None(),
> > +      rootfs,
> > +      None(),
> > +      MS_SLAVE,
> > +      nullptr);
> > +
> > +  if (mount.isError()) {
> > +    return Failure(
> > +        "Failed to mark mount '" + rootfs +
> > +        "' as a slave mount: " + mount.error());
> > +  }
> > +
> > +  mount = fs::mount(
> > +      None(),
> > +      rootfs,
> > +      None(),
> > +      MS_SHARED,
> > +      nullptr);
> > +
> > +  if (mount.isError()) {
> > +    return Failure(
> > +        "Failed to mark mount '" + rootfs +
> > +        "' as a shared mount: " + mount.error());
> > +  }
> > +
> > +  return Nothing();
> > +}
> > +
> > +
> > +Future<bool> AufsBackendProcess::destroy(const string& rootfs)
> > +{
> > +  Try<fs::MountInfoTable> mountTable = fs::MountInfoTable::read();
> > +  if (mountTable.isError()) {
> > +    return Failure("Failed to read mount table: " + mountTable.error());
> > +  }
> > +
> > +  foreach (const fs::MountInfoTable::Entry& entry, mountTable->entries)
> {
> > +    if (entry.target == rootfs) {
> > +      // NOTE: This would fail if the rootfs is still in use.
> > +      Try<Nothing> unmount = fs::unmount(entry.target);
> > +      if (unmount.isError()) {
> > +        return Failure(
> > +            "Failed to destroy aufs-mounted rootfs '" + rootfs + "': " +
> > +            unmount.error());
> > +      }
> > +
> > +      Try<Nothing> rmdir = os::rmdir(rootfs);
> > +      if (rmdir.isError()) {
> > +        return Failure(
> > +            "Failed to remove rootfs mount point '" + rootfs + "': " +
> > +            rmdir.error());
> > +      }
> > +
> > +      return true;
> > +    }
> > +  }
> > +
> > +  return false;
> > +}
> > +
> > +} // namespace slave {
> > +} // namespace internal {
> > +} // namespace mesos {
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/slave/containerizer/mesos/provisioner/backends/aufs.hpp
> > ----------------------------------------------------------------------
> > diff --git a/src/slave/containerizer/mesos/provisioner/backends/aufs.hpp
> b/src/slave/containerizer/mesos/provisioner/backends/aufs.hpp
> > new file mode 100644
> > index 0000000..a5ac13b
> > --- /dev/null
> > +++ b/src/slave/containerizer/mesos/provisioner/backends/aufs.hpp
> > @@ -0,0 +1,70 @@
> > +// 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.
> > +
> > +#ifndef __MESOS_PROVISIONER_AUFS_HPP__
> > +#define __MESOS_PROVISIONER_AUFS_HPP__
> > +
> > +#include "slave/containerizer/mesos/provisioner/backend.hpp"
> > +
> > +namespace mesos {
> > +namespace internal {
> > +namespace slave {
> > +
> > +// Forward declaration.
> > +class AufsBackendProcess;
> > +
> > +
> > +// This backend mounts the images layers to the rootfs using the aufs
> file
> > +// system. The directory layout is as follows:
> > +// <work_dir> ('--work_dir' flag)
> > +// |-- provisioner
> > +//     |-- containers
> > +//         |-- <container-id>
> > +//             |-- backends
> > +//                 |-- aufs
> > +//                    |-- rootfses
> > +//                        |-- <rootfs_id> (the rootfs)
> > +//                    |-- scratch
> > +//                        |-- <rootfs_id> (the scratch space)
> > +//                            |-- workdir
> > +class AufsBackend : public Backend
> > +{
> > +public:
> > +  virtual ~AufsBackend();
> > +
> > +  static Try<process::Owned<Backend>> create(const Flags&);
> > +
> > +  virtual process::Future<Nothing> provision(
> > +      const std::vector<std::string>& layers,
> > +      const std::string& rootfs,
> > +      const std::string& backendDir);
> > +
> > +  virtual process::Future<bool> destroy(const std::string& rootfs);
> > +
> > +private:
> > +  explicit AufsBackend(process::Owned<AufsBackendProcess> process);
> > +
> > +  AufsBackend(const AufsBackend&);
> > +  AufsBackend& operator=(const AufsBackend&);
> > +
> > +  process::Owned<AufsBackendProcess> process;
> > +};
> > +
> > +} // namespace slave {
> > +} // namespace internal {
> > +} // namespace mesos {
> > +
> > +#endif // __MESOS_PROVISIONER_AUFS_HPP__
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/tests/containerizer/provisioner_backend_tests.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/tests/containerizer/provisioner_backend_tests.cpp
> b/src/tests/containerizer/provisioner_backend_tests.cpp
> > index bc04760..f18cc3f 100644
> > --- a/src/tests/containerizer/provisioner_backend_tests.cpp
> > +++ b/src/tests/containerizer/provisioner_backend_tests.cpp
> > @@ -200,6 +200,57 @@ TEST_F(CopyBackendTest, ROOT_CopyBackend)
> >    EXPECT_FALSE(os::exists(rootfs));
> >  }
> >
> > +
> > +class AufsBackendTest : public MountBackendTest {};
> > +
> > +
> > +// Provision a rootfs using multiple layers with the aufs backend.
> > +TEST_F(AufsBackendTest, ROOT_AUFS_AufsBackend)
> > +{
> > +  string layer1 = path::join(os::getcwd(), "source1");
> > +  ASSERT_SOME(os::mkdir(layer1));
> > +  ASSERT_SOME(os::mkdir(path::join(layer1, "dir1")));
> > +  ASSERT_SOME(os::write(path::join(layer1, "dir1", "1"), "1"));
> > +  ASSERT_SOME(os::write(path::join(layer1, "file"), "test1"));
> > +
> > +  string layer2 = path::join(os::getcwd(), "source2");
> > +  ASSERT_SOME(os::mkdir(layer2));
> > +  ASSERT_SOME(os::mkdir(path::join(layer2, "dir2")));
> > +  ASSERT_SOME(os::write(path::join(layer2, "dir2", "2"), "2"));
> > +  ASSERT_SOME(os::write(path::join(layer2, "file"), "test2"));
> > +
> > +  string rootfs = path::join(os::getcwd(), "rootfs");
> > +
> > +  hashmap<string, Owned<Backend>> backends =
> Backend::create(slave::Flags());
> > +  ASSERT_TRUE(backends.contains("aufs"));
> > +
> > +  AWAIT_READY(backends["aufs"]->provision(
> > +      {layer1, layer2},
> > +      rootfs,
> > +      sandbox.get()));
> > +
> > +  EXPECT_TRUE(os::exists(path::join(rootfs, "dir1", "1")));
> > +  EXPECT_SOME_EQ("1", os::read(path::join(rootfs, "dir1", "1")));
> > +
> > +  EXPECT_TRUE(os::exists(path::join(rootfs, "dir2", "2")));
> > +  EXPECT_SOME_EQ("2", os::read(path::join(rootfs, "dir2", "2")));
> > +
> > +  // Last layer should overwrite existing file of earlier layers.
> > +  EXPECT_TRUE(os::exists(path::join(rootfs, "file")));
> > +  EXPECT_SOME_EQ("test2", os::read(path::join(rootfs, "file")));
> > +
> > +  // Rootfs should be writable.
> > +  ASSERT_SOME(os::write(path::join(rootfs, "file"), "test3"));
> > +
> > +  // Files created in rootfs should shadow the files of lower dirs.
> > +  EXPECT_SOME_EQ("test3", os::read(path::join(rootfs, "file")));
> > +  EXPECT_SOME_EQ("test2", os::read(path::join(layer2, "file")));
> > +
> > +  AWAIT_READY(backends["aufs"]->destroy(rootfs));
> > +
> > +  EXPECT_FALSE(os::exists(rootfs));
> > +}
> > +
> >  } // namespace tests {
> >  } // namespace internal {
> >  } // namespace mesos {
> >
> >
> http://git-wip-us.apache.org/repos/asf/mesos/blob/e5358ed1/src/tests/environment.cpp
> > ----------------------------------------------------------------------
> > diff --git a/src/tests/environment.cpp b/src/tests/environment.cpp
> > index 849e9ce..ebfacc3 100644
> > --- a/src/tests/environment.cpp
> > +++ b/src/tests/environment.cpp
> > @@ -517,6 +517,18 @@ public:
> >  };
> >
> >
> > +class AufsFilter : public SupportedFilesystemTestFilter
> > +{
> > +public:
> > +  AufsFilter() : SupportedFilesystemTestFilter("aufs") {}
> > +
> > +  bool disable(const ::testing::TestInfo* test) const
> > +  {
> > +    return fsSupportError.isSome() && matches(test, "AUFS_");
> > +  }
> > +};
> > +
> > +
> >  class OverlayFSFilter : public SupportedFilesystemTestFilter
> >  {
> >  public:
> > @@ -738,6 +750,7 @@ Environment::Environment(const Flags& _flags) :
> flags(_flags)
> >
> >    vector<Owned<TestFilter> > filters;
> >
> > +  filters.push_back(Owned<TestFilter>(new AufsFilter()));
> >    filters.push_back(Owned<TestFilter>(new BenchmarkFilter()));
> >    filters.push_back(Owned<TestFilter>(new CfsFilter()));
> >    filters.push_back(Owned<TestFilter>(new CgroupsFilter()));
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message