Example #1
0
void repository::distributor::update_meta(const entry &package) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const tempfile checksum_tmp = local_system_().small_tempfile();
    try {
      m_fetcher->fetch(checksum_url(package), checksum_tmp.path());
    } catch (std::exception &) {
      BOOST_THROW_EXCEPTION(
          distributor_update_meta_no_package_error()
          << distributor_update_meta_no_package_error::path(checksum_tmp.path())
          << distributor_update_meta_no_package_error::message(
                 "Unable to fetch checksum") << enable_nested_current());
    }
    boost::filesystem::copy_file(
        checksum_tmp.path(), cache_().checksum_path(package),
        boost::filesystem::copy_option::overwrite_if_exists);
    update_file(index_url(package), cache_().index_path(package),
                // \pre index is treated like regular source
                cache_().read_checksum(package).at(format().name.get_index()));
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(distributor_update_meta_error()
                          << distributor_update_meta_error::package(package)
                          << enable_nested_current());
  }
}
Example #2
0
void repository::extractor::install(
    const entry &package, const boost::filesystem::path &destination) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const boost::filesystem::path meta =
        destination / m_config.installation.meta;
    const boost::filesystem::path snp =
        cache_().installation_snapshot_path(package);
    boost::filesystem::path dst = destination;
    if (m_config.installation.data) dst /= m_config.installation.data.get();
    bunsan::filesystem::reset_dir(destination);
    extract(package, dst);
    if (boost::filesystem::exists(meta)) {
      BOOST_ASSERT(!m_config.installation.data);
      BOOST_THROW_EXCEPTION(installation_meta_exists_error()
                            << installation_meta_exists_error::meta(meta));
    }
    boost::filesystem::copy_file(
        snp, meta, boost::filesystem::copy_option::fail_if_exists);
    boost::filesystem::last_write_time(meta, std::time(nullptr));
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(extractor_install_error()
                          << extractor_install_error::package(package)
                          << extractor_install_error::destination(destination)
                          << enable_nested_current());
  }
}
Example #3
0
void repository::builder::build(const entry &package) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const tempfile build_dir_ = local_system_().tempdir_for_build();
    const boost::filesystem::path build_dir = build_dir_.path();
    const boost::filesystem::path src =
        build_dir / m_config.name.dir.get_source();
    const boost::filesystem::path build =
        build_dir / m_config.name.dir.get_build();
    const boost::filesystem::path installation =
        build_dir / m_config.name.dir.get_installation();
    // create/clean directories
    boost::filesystem::create_directory(src);
    boost::filesystem::create_directory(build);
    boost::filesystem::create_directory(installation);
    // unpack source
    snapshot snapshot_;
    unpack_source(package, src, snapshot_);
    get_builder()->install(build_dir / m_config.name.dir.get_source(),
                           build_dir / m_config.name.dir.get_build(),
                           build_dir / m_config.name.dir.get_installation());
    cache_().pack_build(package,
                        build_dir / m_config.name.dir.get_installation());
    write_snapshot(cache_().build_snapshot_path(package), snapshot_);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(builder_build_error()
                          << builder_build_error::package(package)
                          << enable_nested_current());
  }
}
Example #4
0
void repository::cache::verify_and_repair_directory(
    const boost::filesystem::path &path) {
  try {
    if (!path.is_absolute())
      BOOST_THROW_EXCEPTION(
          invalid_configuration_relative_path_error()
          << invalid_configuration_relative_path_error::path(path));
    BUNSAN_LOG_TRACE << "Checking " << path;
    if (!boost::filesystem::is_directory(path)) {
      if (!boost::filesystem::exists(path)) {
        BUNSAN_LOG_ERROR << "Directory " << path << " was not found";
      } else {
        BUNSAN_LOG_ERROR << path
                         << " is not a directory: starting recursive remove";
        boost::filesystem::remove_all(path);
      }
      if (boost::filesystem::create_directory(path))
        BUNSAN_LOG_TRACE << "Created missing " << path << " directory";
    }
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_verify_and_repair_directory_error()
                          << cache_verify_and_repair_directory_error::path(path)
                          << enable_nested_current());
  }
}
Example #5
0
void repository::builder::build_installation(const entry &package) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const tempfile build_dir = local_system_().tempdir_for_build();
    boost::filesystem::path install_dir =
        build_dir.path() / m_config.name.dir.get_installation();
    // unpack
    extractor_().extract_build(package, install_dir);
    snapshot snapshot_ = cache_().read_build_snapshot(package);
    const index deps = cache_().read_index(package);
    for (const auto &i : deps.package.self)
      extractor_().extract_source(package, i.source, install_dir / i.path);
    for (const auto &i : deps.package.import.source)
      unpack_source(i.package, install_dir / i.path, snapshot_);
    for (const auto &i : deps.package.import.package) {
      extractor_().extract_installation(i.package, install_dir / i.path);
      merge_maps(snapshot_, cache_().read_installation_snapshot(i.package));
    }
    // save
    cache_().pack_installation(package, install_dir);
    write_snapshot(cache_().installation_snapshot_path(package), snapshot_);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(builder_build_installation_error()
                          << builder_build_installation_error::package(package)
                          << enable_nested_current());
  }
}
Example #6
0
void repository::cache::initialize(const cache_config &config) {
  try {
    if (!config.root.is_absolute())
      BOOST_THROW_EXCEPTION(
          invalid_configuration_relative_path_error()
          << invalid_configuration_relative_path_error::path(config.root));
    // ignore if directory exists
    boost::filesystem::create_directory(config.root);
    boost::filesystem::create_directory(config.get_source());
    boost::filesystem::create_directory(config.get_package());

    // lock
    if (!config.get_lock().is_absolute())
      BOOST_THROW_EXCEPTION(invalid_configuration_relative_path_error()
                            << invalid_configuration_relative_path_error::path(
                                config.get_lock()));
    if (boost::filesystem::exists(config.get_lock())) {
      if (!boost::filesystem::is_regular_file(config.get_lock()))
        boost::filesystem::remove(config.get_lock());
    }
    if (!boost::filesystem::exists(config.get_lock())) {
      filesystem::ofstream fout(config.get_lock());
      fout.close();
    }
    initialize_meta(config);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_initialize_error() << enable_nested_current());
  }
}
Example #7
0
void repository::cache::verify_and_repair() {
  try {
    bool outdated = false;
    try {
      const auto meta = load_meta();
      if (meta.version != repository::version()) {
        BUNSAN_LOG_INFO << "Cache's version \"" << meta.version
                        << "\" is not equal to repository's version \""
                        << repository::version() << "\", resetting cache";
        outdated = true;
      }
    } catch (std::exception &) {
      BUNSAN_LOG_ERROR << "Unable to read cache's meta, resetting cache";
      outdated = true;
    }
    if (outdated) {
      clean_();
      save_meta();
    }
    verify_and_repair_directory(m_config.get_source());
    verify_and_repair_directory(m_config.get_package());
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_verify_and_repair_error()
                          << enable_nested_current());
  }
}
Example #8
0
boost::filesystem::path find_executable_in_path(
    const boost::filesystem::path &executable) {
  try {
    if (executable != executable.filename())
      BOOST_THROW_EXCEPTION(
          non_basename_executable_error()
          << non_basename_executable_error::executable(executable));

    const boost::filesystem::path exts[] = {"", ".exe", ".com", ".bat"};
    for (const auto &ext : exts) {
      wchar_t buf[MAX_PATH];
      LPWSTR dummy;
      const DWORD size = ::SearchPathW(nullptr, executable.c_str(), ext.c_str(),
                                       MAX_PATH, buf, &dummy);
      BOOST_ASSERT(size < MAX_PATH);
      if (size > 0) return buf;
    }

    BOOST_THROW_EXCEPTION(
        no_executable_in_path_error()
        << no_executable_in_path_error::executable(executable));
  } catch (find_executable_in_path_error &) {
    throw;
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(
        find_executable_in_path_error()
        << find_executable_in_path_error::executable(executable)
        << enable_nested_current());
  }
}
Example #9
0
void repository::extractor::update(const entry &package,
                                   const boost::filesystem::path &destination) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const boost::filesystem::path meta =
        destination / m_config.installation.meta;
    boost::optional<snapshot> snapshot_;
    if (boost::filesystem::is_regular_file(meta)) {
      try {
        snapshot_ = read_snapshot(meta);
      } catch (std::exception &) {
        BUNSAN_LOG_WARNING << "Unable to read snapshot from " << meta
                           << ", falling back to outdated";
      }
    }
    if (!snapshot_ ||
        *snapshot_ != cache_().read_installation_snapshot(package)) {
      BUNSAN_LOG_DEBUG << "\"" << package << "\" installation at "
                       << destination << " is outdated, updating...";
      install(package, destination);
    } else {
      boost::filesystem::last_write_time(meta, std::time(nullptr));
    }
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(extractor_update_error()
                          << extractor_update_error::package(package)
                          << extractor_update_error::destination(destination)
                          << enable_nested_current());
  }
}
Example #10
0
void repository::distributor::create_recursively(
    const boost::filesystem::path &root, const bool strip) {
  try {
    std::unordered_set<std::string> ignore;
    const boost::filesystem::path index_path = root / format().name.get_index();
    if (boost::filesystem::is_regular_file(index_path)) {
      BUNSAN_LOG_DEBUG << "Found index file at " << root
                       << ", trying to create source package...";
      ignore.insert(format().name.get_index());
      create(root, strip);
      index index_;
      index_.load(index_path);
      const std::unordered_set<std::string> sources = index_.sources();
      ignore.insert(sources.begin(), sources.end());
    }
    for (boost::filesystem::directory_iterator i(root), end; i != end; ++i) {
      if (boost::filesystem::is_directory(*i) &&
          ignore.find(i->path().filename().string()) == ignore.end()) {
        create_recursively(i->path(), strip);
      }
    }
  } catch (distributor_create_recursively_error &) {
    throw;
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(distributor_create_recursively_error()
                          << distributor_create_recursively_error::root(root)
                          << distributor_create_recursively_error::strip(strip)
                          << enable_nested_current());
  }
}
Example #11
0
void repository::cache::clean_() {
  try {
    filesystem::reset_dir(m_config.get_source());
    filesystem::reset_dir(m_config.get_package());
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_clean_error() << enable_nested_current());
  }
}
void NamedLogWriter::append(const boost::filesystem::path &path)
{
    try {
        open_(path, true);
    } catch (std::exception &) {
        BOOST_THROW_EXCEPTION(NamedLogWriterAppendError() <<
                              enable_nested_current());
    }
}
Example #13
0
index repository::cache::read_index(const entry &package) {
  try {
    return index(index_path(package)).absolute(package);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_read_index_error()
                          << cache_read_index_error::package(package)
                          << enable_nested_current());
  }
}
void NamedLogWriter::reopen()
{
    try {
        reopen(path_);
    } catch (std::exception &) {
        BOOST_THROW_EXCEPTION(NamedLogWriterReopenError() <<
                              enable_nested_current());
    }
}
Example #15
0
snapshot_entry repository::cache::read_checksum(const entry &package) {
  try {
    return pm::read_checksum(checksum_path(package));
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_read_checksum_error()
                          << cache_read_checksum_error::package(package)
                          << enable_nested_current());
  }
}
Example #16
0
snapshot repository::cache::read_installation_snapshot(const entry &package) {
  try {
    return read_snapshot(installation_snapshot_path(package));
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_read_installation_snapshot_error()
                          << cache_read_installation_snapshot_error::package(
                                 package) << enable_nested_current());
  }
}
Example #17
0
void repository::cache::clean() {
  try {
    verify_and_repair();
    clean_();
  } catch (cache_clean_error &) {
    throw;
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_clean_error() << enable_nested_current());
  }
}
Example #18
0
void repository::cache::unpack_build(
    const entry &package, const boost::filesystem::path &destination) {
  try {
    m_archiver->unpack(build_archive_path(package), destination);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_unpack_build_error()
                          << cache_unpack_build_error::package(package)
                          << cache_unpack_build_error::destination(destination)
                          << enable_nested_current());
  }
}
Example #19
0
void repository::cache::pack_installation(const entry &package,
                                          const boost::filesystem::path &path) {
  try {
    m_archiver->pack_contents(installation_archive_path(package), path);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_pack_installation_error()
                          << cache_pack_installation_error::package(package)
                          << cache_pack_installation_error::path(path)
                          << enable_nested_current());
  }
}
Example #20
0
void repository::extractor::extract_build(
    const entry &package, const boost::filesystem::path &destination) {
  try {
    const tempfile tmp = local_system_().tempdir_for_build();
    cache_().unpack_build(package, tmp.path());
    merge_directories(tmp.path(), destination);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(extractor_extract_build_error()
                          << extractor_extract_build_error::package(package)
                          << extractor_extract_build_error::destination(
                                 destination) << enable_nested_current());
  }
}
Example #21
0
void repository::extractor::extract(
    const entry &package, const boost::filesystem::path &destination) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    filesystem::reset_dir(destination);
    cache_().unpack_installation(package, destination);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(extractor_extract_error()
                          << extractor_extract_error::package(package)
                          << extractor_extract_error::destination(destination)
                          << enable_nested_current());
  }
}
void NamedLogWriter::reopen(const boost::filesystem::path &newPath)
{
    try {
        if (!hasOutput()) {
            BOOST_THROW_EXCEPTION(ClosedWriterError());
        }
        close();
        open(newPath);
    } catch (std::exception &) {
        BOOST_THROW_EXCEPTION(NamedLogWriterReopenError() <<
                              enable_nested_current());
    }
}
Example #23
0
void repository::cache::unpack_source(
    const entry &package, const std::string &source_id,
    const boost::filesystem::path &destination) {
  try {
    distributor_().archiver().unpack(source_path(package, source_id),
                                     destination);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_unpack_source_error()
                          << cache_unpack_source_error::package(package)
                          << cache_unpack_source_error::destination(destination)
                          << enable_nested_current());
  }
}
Example #24
0
void cwd_split::pack(const boost::filesystem::path &archive,
                     const boost::filesystem::path &file) {
    try {
        const boost::filesystem::path file_ = boost::filesystem::absolute(file);
        const boost::filesystem::path archive_ =
            boost::filesystem::absolute(archive);
        pack_from(file_.parent_path(), archive_, file_.filename());
    } catch (std::exception &) {
        BOOST_THROW_EXCEPTION(archiver_pack_error()
                              << archiver_pack_error::archive(archive)
                              << archiver_pack_error::file(file)
                              << enable_nested_current());
    }
}
void NamedLogWriter::rotate(const boost::filesystem::path &renameTo)
{
    try {
        if (!hasOutput()) {
            BOOST_THROW_EXCEPTION(ClosedWriterError());
        }
        close();
        boost::filesystem::rename(path_, renameTo);
        open(path_);
    } catch (std::exception &) {
        BOOST_THROW_EXCEPTION(NamedLogWriterRotateError() <<
                              enable_nested_current());
    }
}
Example #26
0
 /// \return false if !closed()
 void open(const boost::filesystem::path &path)
 {
     try {
         if (!closed()) {
             BOOST_THROW_EXCEPTION(OpenedError());
         }
         path_ = path;
         stream_ = openFd(path, errno_);
         checkError();
     } catch (std::exception &) {
         BOOST_THROW_EXCEPTION(OpenError() <<
                               enable_nested_current());
     }
 }
Example #27
0
bool repository::cache::build_outdated(const entry &package,
                                       const snapshot &snapshot_) {
  try {
    const boost::filesystem::path snp = build_snapshot_path(package);
    const boost::filesystem::path build = build_archive_path(package);
    if (!boost::filesystem::exists(snp) || !boost::filesystem::exists(build))
      return true;
    return snapshot_ != read_snapshot(snp);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(cache_build_outdated_error()
                          << cache_build_outdated_error::package(package)
                          << enable_nested_current());
  }
}
Example #28
0
void repository::builder::build_empty(const entry &package) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    const tempfile build_dir = local_system_().tempdir_for_build();
    // create empty archive
    cache_().pack_build(package, build_dir.path());
    const snapshot snapshot_ = {{package, cache_().read_checksum(package)}};
    write_snapshot(cache_().build_snapshot_path(package), snapshot_);
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(builder_build_empty_error()
                          << builder_build_empty_error::package(package)
                          << enable_nested_current());
  }
}
Example #29
0
void repository::distributor::update_sources(const entry &package) {
  try {
    BUNSAN_LOG_DEBUG << "Starting \"" << package << "\" " << __func__;
    for (const std::string &src_name : cache_().read_index(package).sources()) {
      update_file(source_url(package, src_name),
                  cache_().source_path(package, src_name),
                  cache_().read_checksum(package).at(src_name));
    }
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(distributor_update_sources_error()
                          << distributor_update_sources_error::package(package)
                          << enable_nested_current());
  }
}
Example #30
0
void repository::distributor::create(const boost::filesystem::path &source,
                                     bool strip) {
  try {
    const boost::filesystem::path index_name =
        source / format().name.get_index();
    const boost::filesystem::path checksum_name =
        source / format().name.get_checksum();
    snapshot_entry checksum;
    // we need to save index checksum
    checksum[format().name.get_index()] = pm::checksum(index_name);
    std::unordered_set<std::string> to_remove;
    index index_;
    index_.load(index_name);
    for (const std::string &src_name : index_.sources()) {
      const std::string src_value = src_name + format().name.suffix.archive;
      const boost::filesystem::path src = source / src_name;
      const boost::filesystem::path dst =
          boost::filesystem::absolute(source / src_value);
      if (!boost::filesystem::exists(src))
        BOOST_THROW_EXCEPTION(source_does_not_exist_error()
                              << source_does_not_exist_error::source(src_name)
                              << source_does_not_exist_error::path(src));
      m_archiver->pack_contents(dst, src);
      checksum[src_name] = pm::checksum(source / src_value);
      to_remove.insert(src_name);  // we will remove all sources
    }
    {
      boost::property_tree::ptree checksum_;
      for (const auto &i : checksum)
        checksum_.put(boost::property_tree::ptree::path_type(i.first, '\0'),
                      i.second);
      boost::property_tree::write_info(checksum_name.string(), checksum_);
    }
    // we will remove all files at the end to provide exception guarantee
    // that we will not remove anything accidentally
    if (strip)
      for (const std::string &i : to_remove) {
        boost::filesystem::path path = source / i;
        BUNSAN_LOG_DEBUG << "Removing excess file from source package: "
                         << path;
        boost::filesystem::remove_all(path);
      }
  } catch (std::exception &) {
    BOOST_THROW_EXCEPTION(distributor_create_error()
                          << distributor_create_error::source(source)
                          << distributor_create_error::strip(strip)
                          << enable_nested_current());
  }
}