├── .travis.yml ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── ThriftLibrary.cmake ├── build ├── deps │ └── github_hashes │ │ └── facebook │ │ ├── fbthrift-rev.txt │ │ ├── fbzmq-rev.txt │ │ └── folly-rev.txt ├── fbcode_builder │ ├── .gitignore │ ├── CMake │ │ ├── FBBuildOptions.cmake │ │ ├── FBCMakeParseArgs.cmake │ │ ├── FBCompilerSettings.cmake │ │ ├── FBCompilerSettingsMSVC.cmake │ │ ├── FBCompilerSettingsUnix.cmake │ │ ├── FBPythonBinary.cmake │ │ ├── FBPythonTestAddTests.cmake │ │ ├── FBThriftCppLibrary.cmake │ │ ├── FBThriftLibrary.cmake │ │ ├── FBThriftPyLibrary.cmake │ │ ├── FindGMock.cmake │ │ ├── FindGflags.cmake │ │ ├── FindGlog.cmake │ │ ├── FindLibEvent.cmake │ │ ├── FindLibUnwind.cmake │ │ ├── FindPCRE.cmake │ │ ├── FindRe2.cmake │ │ ├── FindSodium.cmake │ │ ├── fb_py_test_main.py │ │ ├── fb_py_win_main.c │ │ └── make_fbpy_archive.py │ ├── LICENSE │ ├── README.docker │ ├── README.md │ ├── docker_build_with_ccache.sh │ ├── docker_builder.py │ ├── docker_enable_ipv6.sh │ ├── fbcode_builder.py │ ├── fbcode_builder_config.py │ ├── getdeps.py │ ├── getdeps │ │ ├── __init__.py │ │ ├── builder.py │ │ ├── buildopts.py │ │ ├── cache.py │ │ ├── copytree.py │ │ ├── dyndeps.py │ │ ├── envfuncs.py │ │ ├── errors.py │ │ ├── expr.py │ │ ├── fetcher.py │ │ ├── load.py │ │ ├── manifest.py │ │ ├── platform.py │ │ ├── py_wheel_builder.py │ │ ├── runcmd.py │ │ ├── subcmd.py │ │ └── test │ │ │ ├── expr_test.py │ │ │ ├── fixtures │ │ │ └── duplicate │ │ │ │ ├── foo │ │ │ │ └── subdir │ │ │ │ └── foo │ │ │ ├── manifest_test.py │ │ │ ├── platform_test.py │ │ │ └── scratch_test.py │ ├── make_docker_context.py │ ├── manifests │ │ ├── OpenNSA │ │ ├── autoconf │ │ ├── automake │ │ ├── bison │ │ ├── boost │ │ ├── cmake │ │ ├── cpptoml │ │ ├── double-conversion │ │ ├── eden │ │ ├── eden_scm │ │ ├── eden_scm_lib_edenapi_tools │ │ ├── fatal │ │ ├── fb303 │ │ ├── fb303-source │ │ ├── fboss │ │ ├── fbthrift │ │ ├── fbthrift-source │ │ ├── fbzmq │ │ ├── fizz │ │ ├── flex │ │ ├── fmt │ │ ├── folly │ │ ├── gflags │ │ ├── git-lfs │ │ ├── glog │ │ ├── gnu-bash │ │ ├── gnu-coreutils │ │ ├── gnu-grep │ │ ├── gnu-sed │ │ ├── googletest │ │ ├── googletest_1_8 │ │ ├── gperf │ │ ├── iproute2 │ │ ├── jq │ │ ├── katran │ │ ├── libbpf │ │ ├── libbpf_0_2_0_beta │ │ ├── libcurl │ │ ├── libelf │ │ ├── libevent │ │ ├── libgit2 │ │ ├── libmnl │ │ ├── libnl │ │ ├── libsai │ │ ├── libsodium │ │ ├── libtool │ │ ├── libusb │ │ ├── libzmq │ │ ├── lz4 │ │ ├── mononoke │ │ ├── mononoke_integration │ │ ├── mvfst │ │ ├── nghttp2 │ │ ├── ninja │ │ ├── nmap │ │ ├── openr │ │ ├── openssl │ │ ├── osxfuse │ │ ├── patchelf │ │ ├── pcre │ │ ├── perl │ │ ├── pexpect │ │ ├── proxygen │ │ ├── python │ │ ├── python-click │ │ ├── python-dulwich │ │ ├── python-ptyprocess │ │ ├── python-six │ │ ├── python-toml │ │ ├── re2 │ │ ├── rocksdb │ │ ├── rust-shed │ │ ├── snappy │ │ ├── sqlite3 │ │ ├── sqlite3-bin │ │ ├── tcl │ │ ├── tree │ │ ├── wangle │ │ ├── watchman │ │ ├── zlib │ │ └── zstd │ ├── parse_args.py │ ├── shell_builder.py │ ├── shell_quoting.py │ ├── specs │ │ ├── __init__.py │ │ ├── fbthrift.py │ │ ├── fbzmq.py │ │ ├── fizz.py │ │ ├── fmt.py │ │ ├── folly.py │ │ ├── gmock.py │ │ ├── mvfst.py │ │ ├── proxygen.py │ │ ├── proxygen_quic.py │ │ ├── re2.py │ │ ├── rocksdb.py │ │ ├── sodium.py │ │ ├── wangle.py │ │ └── zstd.py │ ├── travis_docker_build.sh │ └── utils.py └── run_fbmeshd.sh └── fbmeshd ├── 802.11s ├── AuthsaeCallbackHelpers.cpp ├── AuthsaeCallbackHelpers.h ├── AuthsaeConfigHelpers.cpp ├── AuthsaeConfigHelpers.h ├── AuthsaeTypes.h ├── NetInterface.cpp ├── NetInterface.h ├── Nl80211Handler.cpp ├── Nl80211Handler.h └── nl80211-copy.h ├── FollySignalHandler.h ├── MeshServiceHandler.h ├── SignalHandler.h ├── common ├── Constants.cpp ├── Constants.h ├── ErrorCodes.h └── Util.h ├── debugfs ├── DebugFsWriter.cpp └── DebugFsWriter.h ├── gateway-connectivity-monitor ├── GatewayConnectivityMonitor.cpp ├── GatewayConnectivityMonitor.h ├── RouteDampener.cpp ├── RouteDampener.h ├── Socket.cpp ├── Socket.h ├── StatsClient.cpp └── StatsClient.h ├── if └── fbmeshd.thrift ├── linkstatsd ├── __init__.py ├── collector.py ├── main.py ├── meshquery.py └── state_manager.py ├── main.cpp ├── nl ├── GenericNetlinkCallbackHandle.h ├── GenericNetlinkFamily.cpp ├── GenericNetlinkFamily.h ├── GenericNetlinkMessage.h ├── GenericNetlinkSocket.h ├── NestedNetlinkAttribute.h ├── NetlinkCallbackHandle.h ├── NetlinkMessage.h ├── NetlinkSocket.h └── TabularNetlinkAttribute.h ├── notifier ├── Notifier.cpp └── Notifier.h ├── py └── setup.py ├── rnl ├── NetlinkMessage.cpp ├── NetlinkMessage.h ├── NetlinkRoute.cpp ├── NetlinkRoute.h ├── NetlinkSocket.cpp ├── NetlinkSocket.h ├── NetlinkTypes.cpp ├── NetlinkTypes.h ├── examples │ └── NetlinkSocketSample.cpp └── tests │ ├── NetlinkMessageTest.cpp │ ├── NetlinkSocketSubscribeTest.cpp │ ├── NetlinkSocketTest.cpp │ └── NetlinkTypesTest.cpp ├── route-update-monitor ├── RouteUpdateMonitor.cpp └── RouteUpdateMonitor.h ├── routing ├── MetricManager.h ├── MetricManager80211s.cpp ├── MetricManager80211s.h ├── PeriodicPinger.cpp ├── PeriodicPinger.h ├── Routing.cpp ├── Routing.h ├── SyncRoutes80211s.cpp ├── SyncRoutes80211s.h ├── UDPRoutingPacketTransport.cpp └── UDPRoutingPacketTransport.h └── tests ├── MockNl80211Handler.h ├── Nl80211HandlerTest.cpp ├── RouteDampenerTest.cpp └── SocketTest.cpp /.travis.yml: -------------------------------------------------------------------------------- 1 | # Facebook projects that use `fbcode_builder` for continuous integration 2 | # share this Travis configuration to run builds via Docker. 3 | 4 | # Docker disables IPv6 in containers by default. Enable it for unit tests that need [::1]. 5 | before_script: 6 | - if [[ "$TRAVIS_OS_NAME" != "osx" ]]; 7 | then 8 | sudo build/fbcode_builder/docker_enable_ipv6.sh; 9 | fi 10 | 11 | env: 12 | global: 13 | - travis_cache_dir=$HOME/travis_ccache 14 | # Travis times out after 50 minutes. Very generously leave 10 minutes 15 | # for setup (e.g. cache download, compression, and upload), so we never 16 | # fail to cache the progress we made. 17 | - docker_build_timeout=40m 18 | 19 | cache: 20 | # Our build caches can be 200-300MB, so increase the timeout to 7 minutes 21 | # to make sure we never fail to cache the progress we made. 22 | timeout: 420 23 | directories: 24 | - $HOME/travis_ccache # see docker_build_with_ccache.sh 25 | 26 | # Ugh, `services:` must be in the matrix, or we get `docker: command not found` 27 | # https://github.com/travis-ci/travis-ci/issues/5142 28 | matrix: 29 | include: 30 | - env: ['os_image=ubuntu:18.04', gcc_version=7] 31 | services: [docker] 32 | 33 | addons: 34 | apt: 35 | packages: python2.7 36 | 37 | script: 38 | # We don't want to write the script inline because of Travis kludginess -- 39 | # it looks like it escapes " and \ in scripts when using `matrix:`. 40 | - ./build/fbcode_builder/travis_docker_build.sh 41 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to. 4 | Please read the [full text](https://code.fb.com/codeofconduct/) 5 | so that you can understand what actions will and will not be tolerated. 6 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to fbmeshd 2 | We want to make contributing to this project as easy and transparent as 3 | possible. 4 | 5 | ## Code of Conduct 6 | The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). 7 | 8 | ## Pull Requests 9 | We actively welcome your pull requests. 10 | 11 | 1. Fork the repo and create your branch from `master`. 12 | 2. If you've added code that should be tested, add tests. 13 | 3. If you've changed APIs, update the documentation. 14 | 4. Ensure the test suite passes. 15 | 5. Make sure your code lints. 16 | 6. If you haven't already, complete the Contributor License Agreement ("CLA"). 17 | 18 | ## Contributor License Agreement ("CLA") 19 | In order to accept your pull request, we need you to submit a CLA. You only need 20 | to do this once to work on any of Facebook's open source projects. 21 | 22 | Complete your CLA here: 23 | 24 | ## Issues 25 | We use GitHub issues to track public bugs. Please ensure your description is 26 | clear and has sufficient instructions to be able to reproduce the issue. 27 | 28 | Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe 29 | disclosure of security bugs. In those cases, please go through the process 30 | outlined on that page and do not file a public issue. 31 | 32 | ## License 33 | By contributing to fbmeshd, you agree that your contributions will be licensed 34 | under the LICENSE file in the root directory of this source tree. 35 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fbmeshd 2 | 3 | `fbmeshd` is the core technology behind Facebook's Self-organizing Mesh Access 4 | (SoMA) network. 5 | 6 | `fbmeshd` uses 802.11s to form links with neighboring nodes in wireless range. 7 | 802.11s path selection and forwarding are disabled and `fbmeshd`'s custom `a12s` 8 | protocol is used for routing over such links. 9 | 10 | ## Device Requirements 11 | 12 | Devices must be using a Qualcomm chipset and have support for `ath10k` drivers. 13 | 14 | ## Getting Started 15 | 16 | `fbmeshd` is built using `CMake`. To run an `fbmeshd` mesh, you need to build and 17 | install `fbmeshd` on a wireless device such as an access point. 18 | 19 | `fbmeshd` can be started using the command in `scripts/` 20 | ``` 21 | $ run_fbmeshd.sh 22 | ``` 23 | which will cause it to form L2 links and handle L3 routing. 24 | 25 | ## Contribute 26 | 27 | Take a look at [`CONTRIBUTING.md`](CONTRIBUTING.md) to get started contributing. 28 | 29 | ## Code of Conduct 30 | 31 | The code of conduct is described in [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md). 32 | 33 | ## License 34 | 35 | `fbmeshd` is MIT licensed. 36 | -------------------------------------------------------------------------------- /build/deps/github_hashes/facebook/fbthrift-rev.txt: -------------------------------------------------------------------------------- 1 | Subproject commit 33d42f092fa63cbe9622cb1af1460844d4c9ba72 2 | -------------------------------------------------------------------------------- /build/deps/github_hashes/facebook/fbzmq-rev.txt: -------------------------------------------------------------------------------- 1 | Subproject commit 5be956cf83535b72f4fdae6f7164507563b3fddb 2 | -------------------------------------------------------------------------------- /build/deps/github_hashes/facebook/folly-rev.txt: -------------------------------------------------------------------------------- 1 | Subproject commit cfa6e9c67c7156b96340482a8398ad9e20077c6e 2 | -------------------------------------------------------------------------------- /build/fbcode_builder/.gitignore: -------------------------------------------------------------------------------- 1 | # Facebook-internal CI builds don't have write permission outside of the 2 | # source tree, so we install all projects into this directory. 3 | /facebook_ci 4 | __pycache__/ 5 | *.pyc 6 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBBuildOptions.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | function (fb_activate_static_library_option) 4 | option(USE_STATIC_DEPS_ON_UNIX 5 | "If enabled, use static dependencies on unix systems. This is generally discouraged." 6 | OFF 7 | ) 8 | # Mark USE_STATIC_DEPS_ON_UNIX as an "advanced" option, since enabling it 9 | # is generally discouraged. 10 | mark_as_advanced(USE_STATIC_DEPS_ON_UNIX) 11 | 12 | if(UNIX AND USE_STATIC_DEPS_ON_UNIX) 13 | SET(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE) 14 | endif() 15 | endfunction() 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBCompilerSettings.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | # This file applies common compiler settings that are shared across 4 | # a number of Facebook opensource projects. 5 | # Please use caution and your best judgement before making changes 6 | # to these shared compiler settings in order to avoid accidentally 7 | # breaking a build in another project! 8 | 9 | if (WIN32) 10 | include(FBCompilerSettingsMSVC) 11 | else() 12 | include(FBCompilerSettingsUnix) 13 | endif() 14 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBCompilerSettingsMSVC.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | # This file applies common compiler settings that are shared across 4 | # a number of Facebook opensource projects. 5 | # Please use caution and your best judgement before making changes 6 | # to these shared compiler settings in order to avoid accidentally 7 | # breaking a build in another project! 8 | 9 | add_compile_options( 10 | /wd4250 # 'class1' : inherits 'class2::member' via dominance 11 | ) 12 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBCompilerSettingsUnix.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | # This file applies common compiler settings that are shared across 4 | # a number of Facebook opensource projects. 5 | # Please use caution and your best judgement before making changes 6 | # to these shared compiler settings in order to avoid accidentally 7 | # breaking a build in another project! 8 | 9 | set(CMAKE_CXX_FLAGS_COMMON "-g -Wall -Wextra -Wno-deprecated -Wno-deprecated-declarations") 10 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_COMMON}") 11 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_COMMON} -O3") 12 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBPythonTestAddTests.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | # Add a command to be emitted to the CTest file 4 | set(ctest_script) 5 | function(add_command CMD) 6 | set(escaped_args "") 7 | foreach(arg ${ARGN}) 8 | # Escape all arguments using "Bracket Argument" syntax 9 | # We could skip this for argument that don't contain any special 10 | # characters if we wanted to make the output slightly more human-friendly. 11 | set(escaped_args "${escaped_args} [==[${arg}]==]") 12 | endforeach() 13 | set(ctest_script "${ctest_script}${CMD}(${escaped_args})\n" PARENT_SCOPE) 14 | endfunction() 15 | 16 | if(NOT EXISTS "${TEST_EXECUTABLE}") 17 | message(FATAL_ERROR "Test executable does not exist: ${TEST_EXECUTABLE}") 18 | endif() 19 | execute_process( 20 | COMMAND ${CMAKE_COMMAND} -E env ${TEST_ENV} "${TEST_INTERPRETER}" "${TEST_EXECUTABLE}" --list-tests 21 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 22 | OUTPUT_VARIABLE output 23 | RESULT_VARIABLE result 24 | ) 25 | if(NOT "${result}" EQUAL 0) 26 | string(REPLACE "\n" "\n " output "${output}") 27 | message( 28 | FATAL_ERROR 29 | "Error running test executable: ${TEST_EXECUTABLE}\n" 30 | "Output:\n" 31 | " ${output}\n" 32 | ) 33 | endif() 34 | 35 | # Parse output 36 | string(REPLACE "\n" ";" tests_list "${output}") 37 | foreach(test_name ${tests_list}) 38 | add_command( 39 | add_test 40 | "${TEST_PREFIX}${test_name}" 41 | ${CMAKE_COMMAND} -E env ${TEST_ENV} 42 | "${TEST_INTERPRETER}" "${TEST_EXECUTABLE}" "${test_name}" 43 | ) 44 | add_command( 45 | set_tests_properties 46 | "${TEST_PREFIX}${test_name}" 47 | PROPERTIES 48 | WORKING_DIRECTORY "${TEST_WORKING_DIR}" 49 | ${TEST_PROPERTIES} 50 | ) 51 | endforeach() 52 | 53 | # Set a list of discovered tests in the parent scope, in case users 54 | # want access to this list as a CMake variable 55 | if(TEST_LIST) 56 | add_command(set ${TEST_LIST} ${tests_list}) 57 | endif() 58 | 59 | file(WRITE "${CTEST_FILE}" "${ctest_script}") 60 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBThriftLibrary.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | include(FBCMakeParseArgs) 4 | include(FBThriftPyLibrary) 5 | include(FBThriftCppLibrary) 6 | 7 | # 8 | # add_fbthrift_library() 9 | # 10 | # This is a convenience function that generates thrift libraries for multiple 11 | # languages. 12 | # 13 | # For example: 14 | # add_fbthrift_library( 15 | # foo foo.thrift 16 | # LANGUAGES cpp py 17 | # SERVICES Foo 18 | # DEPENDS bar) 19 | # 20 | # will be expanded into two separate calls: 21 | # 22 | # add_fbthrift_cpp_library(foo_cpp foo.thrift SERVICES Foo DEPENDS bar_cpp) 23 | # add_fbthrift_py_library(foo_py foo.thrift SERVICES Foo DEPENDS bar_py) 24 | # 25 | function(add_fbthrift_library LIB_NAME THRIFT_FILE) 26 | # Parse the arguments 27 | set(one_value_args PY_NAMESPACE INCLUDE_DIR THRIFT_INCLUDE_DIR) 28 | set(multi_value_args SERVICES DEPENDS LANGUAGES CPP_OPTIONS PY_OPTIONS) 29 | fb_cmake_parse_args( 30 | ARG "" "${one_value_args}" "${multi_value_args}" "${ARGN}" 31 | ) 32 | 33 | if(NOT DEFINED ARG_INCLUDE_DIR) 34 | set(ARG_INCLUDE_DIR "include") 35 | endif() 36 | if(NOT DEFINED ARG_THRIFT_INCLUDE_DIR) 37 | set(ARG_THRIFT_INCLUDE_DIR "${ARG_INCLUDE_DIR}/thrift-files") 38 | endif() 39 | 40 | # CMake 3.12+ adds list(TRANSFORM) which would be nice to use here, but for 41 | # now we still want to support older versions of CMake. 42 | set(CPP_DEPENDS) 43 | set(PY_DEPENDS) 44 | foreach(dep IN LISTS ARG_DEPENDS) 45 | list(APPEND CPP_DEPENDS "${dep}_cpp") 46 | list(APPEND PY_DEPENDS "${dep}_py") 47 | endforeach() 48 | 49 | foreach(lang IN LISTS ARG_LANGUAGES) 50 | if ("${lang}" STREQUAL "cpp") 51 | add_fbthrift_cpp_library( 52 | "${LIB_NAME}_cpp" "${THRIFT_FILE}" 53 | SERVICES ${ARG_SERVICES} 54 | DEPENDS ${CPP_DEPENDS} 55 | OPTIONS ${ARG_CPP_OPTIONS} 56 | INCLUDE_DIR "${ARG_INCLUDE_DIR}" 57 | THRIFT_INCLUDE_DIR "${ARG_THRIFT_INCLUDE_DIR}" 58 | ) 59 | elseif ("${lang}" STREQUAL "py" OR "${lang}" STREQUAL "python") 60 | if (DEFINED ARG_PY_NAMESPACE) 61 | set(namespace_args NAMESPACE "${ARG_PY_NAMESPACE}") 62 | endif() 63 | add_fbthrift_py_library( 64 | "${LIB_NAME}_py" "${THRIFT_FILE}" 65 | SERVICES ${ARG_SERVICES} 66 | ${namespace_args} 67 | DEPENDS ${PY_DEPENDS} 68 | OPTIONS ${ARG_PY_OPTIONS} 69 | THRIFT_INCLUDE_DIR "${ARG_THRIFT_INCLUDE_DIR}" 70 | ) 71 | else() 72 | message( 73 | FATAL_ERROR "unknown language for thrift library ${LIB_NAME}: ${lang}" 74 | ) 75 | endif() 76 | endforeach() 77 | endfunction() 78 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FBThriftPyLibrary.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | 3 | include(FBCMakeParseArgs) 4 | include(FBPythonBinary) 5 | 6 | # Generate a Python library from a thrift file 7 | function(add_fbthrift_py_library LIB_NAME THRIFT_FILE) 8 | # Parse the arguments 9 | set(one_value_args NAMESPACE THRIFT_INCLUDE_DIR) 10 | set(multi_value_args SERVICES DEPENDS OPTIONS) 11 | fb_cmake_parse_args( 12 | ARG "" "${one_value_args}" "${multi_value_args}" "${ARGN}" 13 | ) 14 | 15 | if(NOT DEFINED ARG_THRIFT_INCLUDE_DIR) 16 | set(ARG_THRIFT_INCLUDE_DIR "include/thrift-files") 17 | endif() 18 | 19 | get_filename_component(base ${THRIFT_FILE} NAME_WE) 20 | set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/${THRIFT_FILE}-py") 21 | 22 | # Parse the namespace value 23 | if (NOT DEFINED ARG_NAMESPACE) 24 | set(ARG_NAMESPACE "${base}") 25 | endif() 26 | 27 | string(REPLACE "." "/" namespace_dir "${ARG_NAMESPACE}") 28 | set(py_output_dir "${output_dir}/gen-py/${namespace_dir}") 29 | list(APPEND generated_sources 30 | "${py_output_dir}/__init__.py" 31 | "${py_output_dir}/ttypes.py" 32 | "${py_output_dir}/constants.py" 33 | ) 34 | foreach(service IN LISTS ARG_SERVICES) 35 | list(APPEND generated_sources 36 | ${py_output_dir}/${service}.py 37 | ) 38 | endforeach() 39 | 40 | # Define a dummy interface library to help propagate the thrift include 41 | # directories between dependencies. 42 | add_library("${LIB_NAME}.thrift_includes" INTERFACE) 43 | target_include_directories( 44 | "${LIB_NAME}.thrift_includes" 45 | INTERFACE 46 | "$" 47 | "$" 48 | ) 49 | foreach(dep IN LISTS ARG_DEPENDS) 50 | target_link_libraries( 51 | "${LIB_NAME}.thrift_includes" 52 | INTERFACE "${dep}.thrift_includes" 53 | ) 54 | endforeach() 55 | 56 | # This generator expression gets the list of include directories required 57 | # for all of our dependencies. 58 | # It requires using COMMAND_EXPAND_LISTS in the add_custom_command() call 59 | # below. COMMAND_EXPAND_LISTS is only available in CMake 3.8+ 60 | # If we really had to support older versions of CMake we would probably need 61 | # to use a wrapper script around the thrift compiler that could take the 62 | # include list as a single argument and split it up before invoking the 63 | # thrift compiler. 64 | if (NOT POLICY CMP0067) 65 | message(FATAL_ERROR "add_fbthrift_py_library() requires CMake 3.8+") 66 | endif() 67 | set( 68 | thrift_include_options 69 | "-I;$,;-I;>" 70 | ) 71 | 72 | # Always force generation of "new-style" python classes for Python 2 73 | list(APPEND ARG_OPTIONS "new_style") 74 | # CMake 3.12 is finally getting a list(JOIN) function, but until then 75 | # treating the list as a string and replacing the semicolons is good enough. 76 | string(REPLACE ";" "," GEN_ARG_STR "${ARG_OPTIONS}") 77 | 78 | # Emit the rule to run the thrift compiler 79 | add_custom_command( 80 | OUTPUT 81 | ${generated_sources} 82 | COMMAND_EXPAND_LISTS 83 | COMMAND 84 | "${CMAKE_COMMAND}" -E make_directory "${output_dir}" 85 | COMMAND 86 | "${FBTHRIFT_COMPILER}" 87 | --strict 88 | --gen "py:${GEN_ARG_STR}" 89 | "${thrift_include_options}" 90 | -o "${output_dir}" 91 | "${CMAKE_CURRENT_SOURCE_DIR}/${THRIFT_FILE}" 92 | WORKING_DIRECTORY 93 | "${CMAKE_BINARY_DIR}" 94 | MAIN_DEPENDENCY 95 | "${THRIFT_FILE}" 96 | DEPENDS 97 | "${FBTHRIFT_COMPILER}" 98 | ) 99 | 100 | # We always want to pass the namespace as "" to this call: 101 | # thrift will already emit the files with the desired namespace prefix under 102 | # gen-py. We don't want add_fb_python_library() to prepend the namespace a 103 | # second time. 104 | add_fb_python_library( 105 | "${LIB_NAME}" 106 | BASE_DIR "${output_dir}/gen-py" 107 | NAMESPACE "" 108 | SOURCES ${generated_sources} 109 | DEPENDS ${ARG_DEPENDS} FBThrift::thrift_py 110 | ) 111 | endfunction() 112 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindGMock.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # Find libgmock 3 | # 4 | # LIBGMOCK_DEFINES - List of defines when using libgmock. 5 | # LIBGMOCK_INCLUDE_DIR - where to find gmock/gmock.h, etc. 6 | # LIBGMOCK_LIBRARIES - List of libraries when using libgmock. 7 | # LIBGMOCK_FOUND - True if libgmock found. 8 | 9 | IF (LIBGMOCK_INCLUDE_DIR) 10 | # Already in cache, be silent 11 | SET(LIBGMOCK_FIND_QUIETLY TRUE) 12 | ENDIF () 13 | 14 | find_package(GTest CONFIG QUIET) 15 | if (TARGET GTest::gmock) 16 | get_target_property(LIBGMOCK_DEFINES GTest::gtest INTERFACE_COMPILE_DEFINITIONS) 17 | if (NOT ${LIBGMOCK_DEFINES}) 18 | # Explicitly set to empty string if not found to avoid it being 19 | # set to NOTFOUND and breaking compilation 20 | set(LIBGMOCK_DEFINES "") 21 | endif() 22 | get_target_property(LIBGMOCK_INCLUDE_DIR GTest::gtest INTERFACE_INCLUDE_DIRECTORIES) 23 | set(LIBGMOCK_LIBRARIES GTest::gmock_main GTest::gmock GTest::gtest) 24 | set(LIBGMOCK_FOUND ON) 25 | message(STATUS "Found gmock via config, defines=${LIBGMOCK_DEFINES}, include=${LIBGMOCK_INCLUDE_DIR}, libs=${LIBGMOCK_LIBRARIES}") 26 | else() 27 | 28 | FIND_PATH(LIBGMOCK_INCLUDE_DIR gmock/gmock.h) 29 | 30 | FIND_LIBRARY(LIBGMOCK_MAIN_LIBRARY_DEBUG NAMES gmock_maind) 31 | FIND_LIBRARY(LIBGMOCK_MAIN_LIBRARY_RELEASE NAMES gmock_main) 32 | FIND_LIBRARY(LIBGMOCK_LIBRARY_DEBUG NAMES gmockd) 33 | FIND_LIBRARY(LIBGMOCK_LIBRARY_RELEASE NAMES gmock) 34 | FIND_LIBRARY(LIBGTEST_LIBRARY_DEBUG NAMES gtestd) 35 | FIND_LIBRARY(LIBGTEST_LIBRARY_RELEASE NAMES gtest) 36 | 37 | find_package(Threads REQUIRED) 38 | INCLUDE(SelectLibraryConfigurations) 39 | SELECT_LIBRARY_CONFIGURATIONS(LIBGMOCK_MAIN) 40 | SELECT_LIBRARY_CONFIGURATIONS(LIBGMOCK) 41 | SELECT_LIBRARY_CONFIGURATIONS(LIBGTEST) 42 | 43 | set(LIBGMOCK_LIBRARIES 44 | ${LIBGMOCK_MAIN_LIBRARY} 45 | ${LIBGMOCK_LIBRARY} 46 | ${LIBGTEST_LIBRARY} 47 | Threads::Threads 48 | ) 49 | 50 | if(CMAKE_SYSTEM_NAME STREQUAL "Windows") 51 | # The GTEST_LINKED_AS_SHARED_LIBRARY macro must be set properly on Windows. 52 | # 53 | # There isn't currently an easy way to determine if a library was compiled as 54 | # a shared library on Windows, so just assume we've been built against a 55 | # shared build of gmock for now. 56 | SET(LIBGMOCK_DEFINES "GTEST_LINKED_AS_SHARED_LIBRARY=1" CACHE STRING "") 57 | endif() 58 | 59 | # handle the QUIETLY and REQUIRED arguments and set LIBGMOCK_FOUND to TRUE if 60 | # all listed variables are TRUE 61 | INCLUDE(FindPackageHandleStandardArgs) 62 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( 63 | GMock 64 | DEFAULT_MSG 65 | LIBGMOCK_MAIN_LIBRARY 66 | LIBGMOCK_LIBRARY 67 | LIBGTEST_LIBRARY 68 | LIBGMOCK_LIBRARIES 69 | LIBGMOCK_INCLUDE_DIR 70 | ) 71 | 72 | MARK_AS_ADVANCED( 73 | LIBGMOCK_DEFINES 74 | LIBGMOCK_MAIN_LIBRARY 75 | LIBGMOCK_LIBRARY 76 | LIBGTEST_LIBRARY 77 | LIBGMOCK_LIBRARIES 78 | LIBGMOCK_INCLUDE_DIR 79 | ) 80 | endif() 81 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindGlog.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # - Try to find Glog 3 | # Once done, this will define 4 | # 5 | # GLOG_FOUND - system has Glog 6 | # GLOG_INCLUDE_DIRS - the Glog include directories 7 | # GLOG_LIBRARIES - link these to use Glog 8 | 9 | include(FindPackageHandleStandardArgs) 10 | include(SelectLibraryConfigurations) 11 | 12 | find_library(GLOG_LIBRARY_RELEASE glog 13 | PATHS ${GLOG_LIBRARYDIR}) 14 | find_library(GLOG_LIBRARY_DEBUG glogd 15 | PATHS ${GLOG_LIBRARYDIR}) 16 | 17 | find_path(GLOG_INCLUDE_DIR glog/logging.h 18 | PATHS ${GLOG_INCLUDEDIR}) 19 | 20 | select_library_configurations(GLOG) 21 | 22 | find_package_handle_standard_args(glog DEFAULT_MSG 23 | GLOG_LIBRARY 24 | GLOG_INCLUDE_DIR) 25 | 26 | mark_as_advanced( 27 | GLOG_LIBRARY 28 | GLOG_INCLUDE_DIR) 29 | 30 | set(GLOG_LIBRARIES ${GLOG_LIBRARY}) 31 | set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR}) 32 | 33 | if (NOT TARGET glog::glog) 34 | add_library(glog::glog UNKNOWN IMPORTED) 35 | set_target_properties(glog::glog PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${GLOG_INCLUDE_DIRS}") 36 | set_target_properties(glog::glog PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION "${GLOG_LIBRARIES}") 37 | endif() 38 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindLibEvent.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # - Find LibEvent (a cross event library) 3 | # This module defines 4 | # LIBEVENT_INCLUDE_DIR, where to find LibEvent headers 5 | # LIBEVENT_LIB, LibEvent libraries 6 | # LibEvent_FOUND, If false, do not try to use libevent 7 | 8 | set(LibEvent_EXTRA_PREFIXES /usr/local /opt/local "$ENV{HOME}") 9 | foreach(prefix ${LibEvent_EXTRA_PREFIXES}) 10 | list(APPEND LibEvent_INCLUDE_PATHS "${prefix}/include") 11 | list(APPEND LibEvent_LIB_PATHS "${prefix}/lib") 12 | endforeach() 13 | 14 | find_package(Libevent CONFIG QUIET) 15 | if (TARGET event) 16 | # Re-export the config under our own names 17 | 18 | # Somewhat gross, but some vcpkg installed libevents have a relative 19 | # `include` path exported into LIBEVENT_INCLUDE_DIRS, which triggers 20 | # a cmake error because it resolves to the `include` dir within the 21 | # folly repo, which is not something cmake allows to be in the 22 | # INTERFACE_INCLUDE_DIRECTORIES. Thankfully on such a system the 23 | # actual include directory is already part of the global include 24 | # directories, so we can just skip it. 25 | if (NOT "${LIBEVENT_INCLUDE_DIRS}" STREQUAL "include") 26 | set(LIBEVENT_INCLUDE_DIR ${LIBEVENT_INCLUDE_DIRS}) 27 | else() 28 | set(LIBEVENT_INCLUDE_DIR) 29 | endif() 30 | 31 | # Unfortunately, with a bare target name `event`, downstream consumers 32 | # of the package that depends on `Libevent` located via CONFIG end 33 | # up exporting just a bare `event` in their libraries. This is problematic 34 | # because this in interpreted as just `-levent` with no library path. 35 | # When libevent is not installed in the default installation prefix 36 | # this results in linker errors. 37 | # To resolve this, we ask cmake to lookup the full path to the library 38 | # and use that instead. 39 | cmake_policy(PUSH) 40 | if(POLICY CMP0026) 41 | # Allow reading the LOCATION property 42 | cmake_policy(SET CMP0026 OLD) 43 | endif() 44 | get_target_property(LIBEVENT_LIB event LOCATION) 45 | cmake_policy(POP) 46 | 47 | set(LibEvent_FOUND ${Libevent_FOUND}) 48 | if (NOT LibEvent_FIND_QUIETLY) 49 | message(STATUS "Found libevent from package config include=${LIBEVENT_INCLUDE_DIRS} lib=${LIBEVENT_LIB}") 50 | endif() 51 | else() 52 | find_path(LIBEVENT_INCLUDE_DIR event.h PATHS ${LibEvent_INCLUDE_PATHS}) 53 | find_library(LIBEVENT_LIB NAMES event PATHS ${LibEvent_LIB_PATHS}) 54 | 55 | if (LIBEVENT_LIB AND LIBEVENT_INCLUDE_DIR) 56 | set(LibEvent_FOUND TRUE) 57 | set(LIBEVENT_LIB ${LIBEVENT_LIB}) 58 | else () 59 | set(LibEvent_FOUND FALSE) 60 | endif () 61 | 62 | if (LibEvent_FOUND) 63 | if (NOT LibEvent_FIND_QUIETLY) 64 | message(STATUS "Found libevent: ${LIBEVENT_LIB}") 65 | endif () 66 | else () 67 | if (LibEvent_FIND_REQUIRED) 68 | message(FATAL_ERROR "Could NOT find libevent.") 69 | endif () 70 | message(STATUS "libevent NOT found.") 71 | endif () 72 | 73 | mark_as_advanced( 74 | LIBEVENT_LIB 75 | LIBEVENT_INCLUDE_DIR 76 | ) 77 | endif() 78 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindLibUnwind.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | find_path(LIBUNWIND_INCLUDE_DIR NAMES libunwind.h) 16 | mark_as_advanced(LIBUNWIND_INCLUDE_DIR) 17 | 18 | find_library(LIBUNWIND_LIBRARY NAMES unwind) 19 | mark_as_advanced(LIBUNWIND_LIBRARY) 20 | 21 | include(FindPackageHandleStandardArgs) 22 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( 23 | LIBUNWIND 24 | REQUIRED_VARS LIBUNWIND_LIBRARY LIBUNWIND_INCLUDE_DIR) 25 | 26 | if(LIBUNWIND_FOUND) 27 | set(LIBUNWIND_LIBRARIES ${LIBUNWIND_LIBRARY}) 28 | set(LIBUNWIND_INCLUDE_DIRS ${LIBUNWIND_INCLUDE_DIR}) 29 | endif() 30 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindPCRE.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | include(FindPackageHandleStandardArgs) 3 | find_path(PCRE_INCLUDE_DIR NAMES pcre.h) 4 | find_library(PCRE_LIBRARY NAMES pcre) 5 | find_package_handle_standard_args( 6 | PCRE 7 | DEFAULT_MSG 8 | PCRE_LIBRARY 9 | PCRE_INCLUDE_DIR 10 | ) 11 | mark_as_advanced(PCRE_INCLUDE_DIR PCRE_LIBRARY) 12 | -------------------------------------------------------------------------------- /build/fbcode_builder/CMake/FindRe2.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This software may be used and distributed according to the terms of the 4 | # GNU General Public License version 2. 5 | 6 | find_library(RE2_LIBRARY re2) 7 | mark_as_advanced(RE2_LIBRARY) 8 | 9 | find_path(RE2_INCLUDE_DIR NAMES re2/re2.h) 10 | mark_as_advanced(RE2_INCLUDE_DIR) 11 | 12 | include(FindPackageHandleStandardArgs) 13 | FIND_PACKAGE_HANDLE_STANDARD_ARGS( 14 | RE2 15 | REQUIRED_VARS RE2_LIBRARY RE2_INCLUDE_DIR) 16 | 17 | if(RE2_FOUND) 18 | set(RE2_LIBRARY ${RE2_LIBRARY}) 19 | set(RE2_INCLUDE_DIR, ${RE2_INCLUDE_DIR}) 20 | endif() 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Facebook, Inc. and its affiliates. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /build/fbcode_builder/README.docker: -------------------------------------------------------------------------------- 1 | ## Debugging Docker builds 2 | 3 | To debug a a build failure, start up a shell inside the just-failed image as 4 | follows: 5 | 6 | ``` 7 | docker ps -a | head # Grab the container ID 8 | docker commit CONTAINER_ID # Grab the SHA string 9 | docker run -it SHA_STRING /bin/bash 10 | # Debug as usual, e.g. `./run-cmake.sh Debug`, `make`, `apt-get install gdb` 11 | ``` 12 | 13 | ## A note on Docker security 14 | 15 | While the Dockerfile generated above is quite simple, you must be aware that 16 | using Docker to run arbitrary code can present significant security risks: 17 | 18 | - Code signature validation is off by default (as of 2016), exposing you to 19 | man-in-the-middle malicious code injection. 20 | 21 | - You implicitly trust the world -- a Dockerfile cannot annotate that 22 | you trust the image `debian:8.6` because you trust a particular 23 | certificate -- rather, you trust the name, and that it will never be 24 | hijacked. 25 | 26 | - Sandboxing in the Linux kernel is not perfect, and the builds run code as 27 | root. Any compromised code can likely escalate to the host system. 28 | 29 | Specifically, you must be very careful only to add trusted OS images to the 30 | build flow. 31 | 32 | Consider setting this variable before running any Docker container -- this 33 | will validate a signature on the base image before running code from it: 34 | 35 | ``` 36 | export DOCKER_CONTENT_TRUST=1 37 | ``` 38 | 39 | Note that unless you go through the extra steps of notarizing the resulting 40 | images, you will have to disable trust to enter intermediate images, e.g. 41 | 42 | ``` 43 | DOCKER_CONTENT_TRUST= docker run -it YOUR_IMAGE_ID /bin/bash 44 | ``` 45 | -------------------------------------------------------------------------------- /build/fbcode_builder/README.md: -------------------------------------------------------------------------------- 1 | # Easy builds for Facebook projects 2 | 3 | This directory contains tools designed to simplify continuous-integration 4 | (and other builds) of Facebook open source projects. In particular, this helps 5 | manage builds for cross-project dependencies. 6 | 7 | The main entry point is the `getdeps.py` script. This script has several 8 | subcommands, but the most notable is the `build` command. This will download 9 | and build all dependencies for a project, and then build the project itself. 10 | 11 | ## Deployment 12 | 13 | This directory is copied literally into a number of different Facebook open 14 | source repositories. Any change made to code in this directory will be 15 | automatically be replicated by our open source tooling into all GitHub hosted 16 | repositories that use `fbcode_builder`. Typically this directory is copied 17 | into the open source repositories as `build/fbcode_builder/`. 18 | 19 | 20 | # Project Configuration Files 21 | 22 | The `manifests` subdirectory contains configuration files for many different 23 | projects, describing how to build each project. These files also list 24 | dependencies between projects, enabling `getdeps.py` to build all dependencies 25 | for a project before building the project itself. 26 | 27 | 28 | # Shared CMake utilities 29 | 30 | Since this directory is copied into many Facebook open source repositories, 31 | it is also used to help share some CMake utility files across projects. The 32 | `CMake/` subdirectory contains a number of `.cmake` files that are shared by 33 | the CMake-based build systems across several different projects. 34 | 35 | 36 | # Older Build Scripts 37 | 38 | This directory also still contains a handful of older build scripts that 39 | pre-date the current `getdeps.py` build system. Most of the other `.py` files 40 | in this top directory, apart from `getdeps.py` itself, are from this older 41 | build system. This older system is only used by a few remaining projects, and 42 | new projects should generally use the newer `getdeps.py` script, by adding a 43 | new configuration file in the `manifests/` subdirectory. 44 | -------------------------------------------------------------------------------- /build/fbcode_builder/docker_enable_ipv6.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | 4 | 5 | # `daemon.json` is normally missing, but let's log it in case that changes. 6 | touch /etc/docker/daemon.json 7 | service docker stop 8 | echo '{"ipv6": true, "fixed-cidr-v6": "2001:db8:1::/64"}' > /etc/docker/daemon.json 9 | service docker start 10 | # Fail early if docker failed on start -- add `- sudo dockerd` to debug. 11 | docker info 12 | # Paranoia log: what if our config got overwritten? 13 | cat /etc/docker/daemon.json 14 | -------------------------------------------------------------------------------- /build/fbcode_builder/fbcode_builder_config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 'Demo config, so that `make_docker_context.py --help` works in this directory.' 8 | 9 | config = { 10 | 'fbcode_builder_spec': lambda _builder: { 11 | 'depends_on': [], 12 | 'steps': [], 13 | }, 14 | 'github_project': 'demo/project', 15 | } 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/fbmeshd/13bb3bc12b07632d5e2b4770bae0d0c154d6b2c6/build/fbcode_builder/getdeps/__init__.py -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/cache.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | 9 | class ArtifactCache(object): 10 | """The ArtifactCache is a small abstraction that allows caching 11 | named things in some external storage mechanism. 12 | The primary use case is for storing the build products on CI 13 | systems to accelerate the build""" 14 | 15 | def download_to_file(self, name, dest_file_name): 16 | """If `name` exists in the cache, download it and place it 17 | in the specified `dest_file_name` location on the filesystem. 18 | If a transient issue was encountered a TransientFailure shall 19 | be raised. 20 | If `name` doesn't exist in the cache `False` shall be returned. 21 | If `dest_file_name` was successfully updated `True` shall be 22 | returned. 23 | All other conditions shall raise an appropriate exception.""" 24 | return False 25 | 26 | def upload_from_file(self, name, source_file_name): 27 | """Causes `name` to be populated in the cache by uploading 28 | the contents of `source_file_name` to the storage system. 29 | If a transient issue was encountered a TransientFailure shall 30 | be raised. 31 | If the upload failed for some other reason, an appropriate 32 | exception shall be raised.""" 33 | pass 34 | 35 | 36 | def create_cache(): 37 | """This function is monkey patchable to provide an actual 38 | implementation""" 39 | return None 40 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/copytree.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | import os 9 | import shutil 10 | import subprocess 11 | 12 | from .platform import is_windows 13 | 14 | 15 | PREFETCHED_DIRS = set() 16 | 17 | 18 | def containing_repo_type(path): 19 | while True: 20 | if os.path.exists(os.path.join(path, ".git")): 21 | return ("git", path) 22 | if os.path.exists(os.path.join(path, ".hg")): 23 | return ("hg", path) 24 | 25 | parent = os.path.dirname(path) 26 | if parent == path: 27 | return None, None 28 | path = parent 29 | 30 | 31 | def find_eden_root(dirpath): 32 | """If the specified directory is inside an EdenFS checkout, returns 33 | the canonical absolute path to the root of that checkout. 34 | 35 | Returns None if the specified directory is not in an EdenFS checkout. 36 | """ 37 | if is_windows(): 38 | repo_type, repo_root = containing_repo_type(dirpath) 39 | if repo_root is not None: 40 | if os.path.exists(os.path.join(repo_root, ".eden", "config")): 41 | return os.path.realpath(repo_root) 42 | return None 43 | 44 | try: 45 | return os.readlink(os.path.join(dirpath, ".eden", "root")) 46 | except OSError: 47 | return None 48 | 49 | 50 | def prefetch_dir_if_eden(dirpath): 51 | """After an amend/rebase, Eden may need to fetch a large number 52 | of trees from the servers. The simplistic single threaded walk 53 | performed by copytree makes this more expensive than is desirable 54 | so we help accelerate things by performing a prefetch on the 55 | source directory""" 56 | global PREFETCHED_DIRS 57 | if dirpath in PREFETCHED_DIRS: 58 | return 59 | root = find_eden_root(dirpath) 60 | if root is None: 61 | return 62 | rel = os.path.relpath(dirpath, root) 63 | print("Prefetching %s..." % rel) 64 | subprocess.call( 65 | ["edenfsctl", "prefetch", "--repo", root, "--silent", "%s/**" % rel] 66 | ) 67 | PREFETCHED_DIRS.add(dirpath) 68 | 69 | 70 | def copytree(src_dir, dest_dir, ignore=None): 71 | """Recursively copy the src_dir to the dest_dir, filtering 72 | out entries using the ignore lambda. The behavior of the 73 | ignore lambda must match that described by `shutil.copytree`. 74 | This `copytree` function knows how to prefetch data when 75 | running in an eden repo. 76 | TODO: I'd like to either extend this or add a variant that 77 | uses watchman to mirror src_dir into dest_dir. 78 | """ 79 | prefetch_dir_if_eden(src_dir) 80 | return shutil.copytree(src_dir, dest_dir, ignore=ignore) 81 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/errors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | 9 | class TransientFailure(Exception): 10 | """Raising this error causes getdeps to return with an error code 11 | that Sandcastle will consider to be a retryable transient 12 | infrastructure error""" 13 | 14 | pass 15 | 16 | 17 | class ManifestNotFound(Exception): 18 | def __init__(self, manifest_name): 19 | super(Exception, self).__init__("Unable to find manifest '%s'" % manifest_name) 20 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/platform.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | import re 9 | import shlex 10 | import sys 11 | 12 | 13 | def is_windows(): 14 | """Returns true if the system we are currently running on 15 | is a Windows system""" 16 | return sys.platform.startswith("win") 17 | 18 | 19 | def get_linux_type(): 20 | try: 21 | with open("/etc/os-release") as f: 22 | data = f.read() 23 | except EnvironmentError: 24 | return (None, None) 25 | 26 | os_vars = {} 27 | for line in data.splitlines(): 28 | parts = line.split("=", 1) 29 | if len(parts) != 2: 30 | continue 31 | key = parts[0].strip() 32 | value_parts = shlex.split(parts[1].strip()) 33 | if not value_parts: 34 | value = "" 35 | else: 36 | value = value_parts[0] 37 | os_vars[key] = value 38 | 39 | name = os_vars.get("NAME") 40 | if name: 41 | name = name.lower() 42 | name = re.sub("linux", "", name) 43 | name = name.strip() 44 | 45 | version_id = os_vars.get("VERSION_ID") 46 | if version_id: 47 | version_id = version_id.lower() 48 | 49 | return "linux", name, version_id 50 | 51 | 52 | class HostType(object): 53 | def __init__(self, ostype=None, distro=None, distrovers=None): 54 | if ostype is None: 55 | distro = None 56 | distrovers = None 57 | if sys.platform.startswith("linux"): 58 | ostype, distro, distrovers = get_linux_type() 59 | elif sys.platform.startswith("darwin"): 60 | ostype = "darwin" 61 | elif is_windows(): 62 | ostype = "windows" 63 | distrovers = str(sys.getwindowsversion().major) 64 | else: 65 | ostype = sys.platform 66 | 67 | # The operating system type 68 | self.ostype = ostype 69 | # The distribution, if applicable 70 | self.distro = distro 71 | # The OS/distro version if known 72 | self.distrovers = distrovers 73 | 74 | def is_windows(self): 75 | return self.ostype == "windows" 76 | 77 | def is_darwin(self): 78 | return self.ostype == "darwin" 79 | 80 | def is_linux(self): 81 | return self.ostype == "linux" 82 | 83 | def as_tuple_string(self): 84 | return "%s-%s-%s" % ( 85 | self.ostype, 86 | self.distro or "none", 87 | self.distrovers or "none", 88 | ) 89 | 90 | def get_package_manager(self): 91 | if not self.is_linux(): 92 | return None 93 | if self.distro in ("fedora", "centos"): 94 | return "rpm" 95 | if self.distro in ("debian", "ubuntu"): 96 | return "deb" 97 | return None 98 | 99 | @staticmethod 100 | def from_tuple_string(s): 101 | ostype, distro, distrovers = s.split("-") 102 | return HostType(ostype=ostype, distro=distro, distrovers=distrovers) 103 | 104 | def __eq__(self, b): 105 | return ( 106 | self.ostype == b.ostype 107 | and self.distro == b.distro 108 | and self.distrovers == b.distrovers 109 | ) 110 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/subcmd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | 9 | class SubCmd(object): 10 | NAME = None 11 | HELP = None 12 | 13 | def run(self, args): 14 | """ perform the command """ 15 | return 0 16 | 17 | def setup_parser(self, parser): 18 | # Subclasses should override setup_parser() if they have any 19 | # command line options or arguments. 20 | pass 21 | 22 | 23 | CmdTable = [] 24 | 25 | 26 | def add_subcommands(parser, common_args, cmd_table=CmdTable): 27 | """ Register parsers for the defined commands with the provided parser """ 28 | for cls in cmd_table: 29 | command = cls() 30 | command_parser = parser.add_parser( 31 | command.NAME, help=command.HELP, parents=[common_args] 32 | ) 33 | command.setup_parser(command_parser) 34 | command_parser.set_defaults(func=command.run) 35 | 36 | 37 | def cmd(name, help=None, cmd_table=CmdTable): 38 | """ 39 | @cmd() is a decorator that can be used to help define Subcmd instances 40 | 41 | Example usage: 42 | 43 | @subcmd('list', 'Show the result list') 44 | class ListCmd(Subcmd): 45 | def run(self, args): 46 | # Perform the command actions here... 47 | pass 48 | """ 49 | 50 | def wrapper(cls): 51 | class SubclassedCmd(cls): 52 | NAME = name 53 | HELP = help 54 | 55 | cmd_table.append(SubclassedCmd) 56 | return SubclassedCmd 57 | 58 | return wrapper 59 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/test/expr_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | import unittest 9 | 10 | from ..expr import parse_expr 11 | 12 | 13 | class ExprTest(unittest.TestCase): 14 | def test_equal(self): 15 | valid_variables = {"foo", "some_var", "another_var"} 16 | e = parse_expr("foo=bar", valid_variables) 17 | self.assertTrue(e.eval({"foo": "bar"})) 18 | self.assertFalse(e.eval({"foo": "not-bar"})) 19 | self.assertFalse(e.eval({"not-foo": "bar"})) 20 | 21 | def test_not_equal(self): 22 | valid_variables = {"foo"} 23 | e = parse_expr("not(foo=bar)", valid_variables) 24 | self.assertFalse(e.eval({"foo": "bar"})) 25 | self.assertTrue(e.eval({"foo": "not-bar"})) 26 | 27 | def test_bad_not(self): 28 | valid_variables = {"foo"} 29 | with self.assertRaises(Exception): 30 | parse_expr("foo=not(bar)", valid_variables) 31 | 32 | def test_bad_variable(self): 33 | valid_variables = {"bar"} 34 | with self.assertRaises(Exception): 35 | parse_expr("foo=bar", valid_variables) 36 | 37 | def test_all(self): 38 | valid_variables = {"foo", "baz"} 39 | e = parse_expr("all(foo = bar, baz = qux)", valid_variables) 40 | self.assertTrue(e.eval({"foo": "bar", "baz": "qux"})) 41 | self.assertFalse(e.eval({"foo": "bar", "baz": "nope"})) 42 | self.assertFalse(e.eval({"foo": "nope", "baz": "nope"})) 43 | 44 | def test_any(self): 45 | valid_variables = {"foo", "baz"} 46 | e = parse_expr("any(foo = bar, baz = qux)", valid_variables) 47 | self.assertTrue(e.eval({"foo": "bar", "baz": "qux"})) 48 | self.assertTrue(e.eval({"foo": "bar", "baz": "nope"})) 49 | self.assertFalse(e.eval({"foo": "nope", "baz": "nope"})) 50 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/test/fixtures/duplicate/foo: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = foo 3 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/test/fixtures/duplicate/subdir/foo: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = foo 3 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/test/platform_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function, unicode_literals 7 | 8 | import unittest 9 | 10 | from ..platform import HostType 11 | 12 | 13 | class PlatformTest(unittest.TestCase): 14 | def test_create(self): 15 | p = HostType() 16 | self.assertNotEqual(p.ostype, None, msg="probed and returned something") 17 | 18 | tuple_string = p.as_tuple_string() 19 | round_trip = HostType.from_tuple_string(tuple_string) 20 | self.assertEqual(round_trip, p) 21 | 22 | def test_rendering_of_none(self): 23 | p = HostType(ostype="foo") 24 | self.assertEqual(p.as_tuple_string(), "foo-none-none") 25 | 26 | def test_is_methods(self): 27 | p = HostType(ostype="windows") 28 | self.assertTrue(p.is_windows()) 29 | self.assertFalse(p.is_darwin()) 30 | self.assertFalse(p.is_linux()) 31 | 32 | p = HostType(ostype="darwin") 33 | self.assertFalse(p.is_windows()) 34 | self.assertTrue(p.is_darwin()) 35 | self.assertFalse(p.is_linux()) 36 | 37 | p = HostType(ostype="linux") 38 | self.assertFalse(p.is_windows()) 39 | self.assertFalse(p.is_darwin()) 40 | self.assertTrue(p.is_linux()) 41 | -------------------------------------------------------------------------------- /build/fbcode_builder/getdeps/test/scratch_test.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # 3 | # This source code is licensed under the MIT license found in the 4 | # LICENSE file in the root directory of this source tree. 5 | 6 | from __future__ import absolute_import, division, print_function 7 | 8 | import unittest 9 | 10 | from ..buildopts import find_existing_win32_subst_for_path 11 | 12 | 13 | class Win32SubstTest(unittest.TestCase): 14 | def test_no_existing_subst(self): 15 | self.assertIsNone( 16 | find_existing_win32_subst_for_path( 17 | r"C:\users\alice\appdata\local\temp\fbcode_builder_getdeps", 18 | subst_mapping={}, 19 | ) 20 | ) 21 | self.assertIsNone( 22 | find_existing_win32_subst_for_path( 23 | r"C:\users\alice\appdata\local\temp\fbcode_builder_getdeps", 24 | subst_mapping={"X:\\": r"C:\users\alice\appdata\local\temp\other"}, 25 | ) 26 | ) 27 | 28 | def test_exact_match_returns_drive_path(self): 29 | self.assertEqual( 30 | find_existing_win32_subst_for_path( 31 | r"C:\temp\fbcode_builder_getdeps", 32 | subst_mapping={"X:\\": r"C:\temp\fbcode_builder_getdeps"}, 33 | ), 34 | "X:\\", 35 | ) 36 | self.assertEqual( 37 | find_existing_win32_subst_for_path( 38 | r"C:/temp/fbcode_builder_getdeps", 39 | subst_mapping={"X:\\": r"C:/temp/fbcode_builder_getdeps"}, 40 | ), 41 | "X:\\", 42 | ) 43 | 44 | def test_multiple_exact_matches_returns_arbitrary_drive_path(self): 45 | self.assertIn( 46 | find_existing_win32_subst_for_path( 47 | r"C:\temp\fbcode_builder_getdeps", 48 | subst_mapping={ 49 | "X:\\": r"C:\temp\fbcode_builder_getdeps", 50 | "Y:\\": r"C:\temp\fbcode_builder_getdeps", 51 | "Z:\\": r"C:\temp\fbcode_builder_getdeps", 52 | }, 53 | ), 54 | ("X:\\", "Y:\\", "Z:\\"), 55 | ) 56 | 57 | def test_drive_letter_is_case_insensitive(self): 58 | self.assertEqual( 59 | find_existing_win32_subst_for_path( 60 | r"C:\temp\fbcode_builder_getdeps", 61 | subst_mapping={"X:\\": r"c:\temp\fbcode_builder_getdeps"}, 62 | ), 63 | "X:\\", 64 | ) 65 | 66 | def test_path_components_are_case_insensitive(self): 67 | self.assertEqual( 68 | find_existing_win32_subst_for_path( 69 | r"C:\TEMP\FBCODE_builder_getdeps", 70 | subst_mapping={"X:\\": r"C:\temp\fbcode_builder_getdeps"}, 71 | ), 72 | "X:\\", 73 | ) 74 | self.assertEqual( 75 | find_existing_win32_subst_for_path( 76 | r"C:\temp\fbcode_builder_getdeps", 77 | subst_mapping={"X:\\": r"C:\TEMP\FBCODE_builder_getdeps"}, 78 | ), 79 | "X:\\", 80 | ) 81 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/OpenNSA: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = OpenNSA 3 | 4 | [download] 5 | url = https://docs.broadcom.com/docs-and-downloads/csg/opennsa-6.5.19.tgz 6 | sha256 = 80c3a26f688dd7fc08880fdbbad9ac3424b435697b0ccb889487f55f2bc425c4 7 | 8 | [build] 9 | builder = nop 10 | subdir = opennsa-6.5.19 11 | 12 | [install.files] 13 | lib/x86-64 = lib 14 | include = include 15 | src/gpl-modules/systems/bde/linux/include = include/systems/bde/linux 16 | src/gpl-modules/include/ibde.h = include/ibde.h 17 | src/gpl-modules = src/gpl-modules 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/autoconf: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = autoconf 3 | 4 | [rpms] 5 | autoconf 6 | 7 | [debs] 8 | autoconf 9 | 10 | [download] 11 | url = http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz 12 | sha256 = 954bd69b391edc12d6a4a51a2dd1476543da5c6bbf05a95b59dc0dd6fd4c2969 13 | 14 | [build] 15 | builder = autoconf 16 | subdir = autoconf-2.69 17 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/automake: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = automake 3 | 4 | [rpms] 5 | automake 6 | 7 | [debs] 8 | automake 9 | 10 | [download] 11 | url = http://ftp.gnu.org/gnu/automake/automake-1.16.1.tar.gz 12 | sha256 = 608a97523f97db32f1f5d5615c98ca69326ced2054c9f82e65bade7fc4c9dea8 13 | 14 | [build] 15 | builder = autoconf 16 | subdir = automake-1.16.1 17 | 18 | [dependencies] 19 | autoconf 20 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/bison: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = bison 3 | 4 | [rpms] 5 | bison 6 | 7 | [debs] 8 | bison 9 | 10 | [download.not(os=windows)] 11 | url = https://mirrors.kernel.org/gnu/bison/bison-3.3.tar.gz 12 | sha256 = fdeafb7fffade05604a61e66b8c040af4b2b5cbb1021dcfe498ed657ac970efd 13 | 14 | [download.os=windows] 15 | url = https://github.com/lexxmark/winflexbison/releases/download/v2.5.17/winflexbison-2.5.17.zip 16 | sha256 = 3dc27a16c21b717bcc5de8590b564d4392a0b8577170c058729d067d95ded825 17 | 18 | [build.not(os=windows)] 19 | builder = autoconf 20 | subdir = bison-3.3 21 | 22 | [build.os=windows] 23 | builder = nop 24 | 25 | [install.files.os=windows] 26 | data = bin/data 27 | win_bison.exe = bin/bison.exe 28 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/boost: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = boost 3 | 4 | [download.not(os=windows)] 5 | url = https://versaweb.dl.sourceforge.net/project/boost/boost/1.69.0/boost_1_69_0.tar.bz2 6 | sha256 = 8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406 7 | 8 | [download.os=windows] 9 | url = https://versaweb.dl.sourceforge.net/project/boost/boost/1.69.0/boost_1_69_0.zip 10 | sha256 = d074bcbcc0501c4917b965fc890e303ee70d8b01ff5712bae4a6c54f2b6b4e52 11 | 12 | [preinstalled.env] 13 | BOOST_ROOT_1_69_0 14 | 15 | [debs] 16 | libboost-all-dev 17 | 18 | [rpms] 19 | boost 20 | boost-math 21 | boost-test 22 | boost-fiber 23 | boost-graph 24 | boost-log 25 | boost-openmpi 26 | boost-timer 27 | boost-chrono 28 | boost-locale 29 | boost-thread 30 | boost-atomic 31 | boost-random 32 | boost-static 33 | boost-contract 34 | boost-date-time 35 | boost-iostreams 36 | boost-container 37 | boost-coroutine 38 | boost-filesystem 39 | boost-system 40 | boost-stacktrace 41 | boost-regex 42 | boost-devel 43 | boost-context 44 | boost-python3-devel 45 | boost-type_erasure 46 | boost-wave 47 | boost-python3 48 | boost-serialization 49 | boost-program-options 50 | 51 | [build] 52 | builder = boost 53 | 54 | [b2.args] 55 | --with-atomic 56 | --with-chrono 57 | --with-container 58 | --with-context 59 | --with-contract 60 | --with-coroutine 61 | --with-date_time 62 | --with-exception 63 | --with-fiber 64 | --with-filesystem 65 | --with-graph 66 | --with-graph_parallel 67 | --with-iostreams 68 | --with-locale 69 | --with-log 70 | --with-math 71 | --with-mpi 72 | --with-program_options 73 | --with-python 74 | --with-random 75 | --with-regex 76 | --with-serialization 77 | --with-stacktrace 78 | --with-system 79 | --with-test 80 | --with-thread 81 | --with-timer 82 | --with-type_erasure 83 | --with-wave 84 | 85 | [b2.args.os=darwin] 86 | toolset=clang 87 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/cmake: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = cmake 3 | 4 | [rpms] 5 | cmake 6 | 7 | # All current deb based distros have a cmake that is too old 8 | #[debs] 9 | #cmake 10 | 11 | [dependencies] 12 | ninja 13 | 14 | [download.os=windows] 15 | url = https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-win64-x64.zip 16 | sha256 = 40e8140d68120378262322bbc8c261db8d184d7838423b2e5bf688a6209d3807 17 | 18 | [download.os=darwin] 19 | url = https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Darwin-x86_64.tar.gz 20 | sha256 = a02ad0d5b955dfad54c095bd7e937eafbbbfe8a99860107025cc442290a3e903 21 | 22 | [download.os=linux] 23 | url = https://github.com/Kitware/CMake/releases/download/v3.14.0/cmake-3.14.0-Linux-x86_64.tar.gz 24 | sha256 = 91dc9af7345e458eb10c853aa875e591efb7079a045641685ddec8d973c2b2bc 25 | 26 | [build.os=windows] 27 | builder = nop 28 | subdir = cmake-3.14.0-win64-x64 29 | 30 | [build.os=darwin] 31 | builder = nop 32 | subdir = cmake-3.14.0-Darwin-x86_64 33 | 34 | [install.files.os=darwin] 35 | CMake.app/Contents/bin = bin 36 | CMake.app/Contents/share = share 37 | 38 | [build.os=linux] 39 | builder = nop 40 | subdir = cmake-3.14.0-Linux-x86_64 41 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/cpptoml: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = cpptoml 3 | 4 | [download] 5 | url = https://github.com/skystrife/cpptoml/archive/v0.1.1.tar.gz 6 | sha256 = 23af72468cfd4040984d46a0dd2a609538579c78ddc429d6b8fd7a10a6e24403 7 | 8 | [build] 9 | builder = cmake 10 | subdir = cpptoml-0.1.1 11 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/double-conversion: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = double-conversion 3 | 4 | [download] 5 | url = https://github.com/google/double-conversion/archive/v3.1.4.tar.gz 6 | sha256 = 95004b65e43fefc6100f337a25da27bb99b9ef8d4071a36a33b5e83eb1f82021 7 | 8 | [build] 9 | builder = cmake 10 | subdir = double-conversion-3.1.4 11 | 12 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/eden: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = eden 3 | fbsource_path = fbcode/eden 4 | shipit_project = eden 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookexperimental/eden.git 9 | 10 | [build] 11 | builder = cmake 12 | 13 | [dependencies] 14 | googletest 15 | folly 16 | fbthrift 17 | fb303 18 | cpptoml 19 | rocksdb 20 | re2 21 | libgit2 22 | lz4 23 | pexpect 24 | python-toml 25 | 26 | [dependencies.fb=on] 27 | rust 28 | 29 | # macOS ships with sqlite3, and some of the core system 30 | # frameworks require that that version be linked rather 31 | # than the one we might build for ourselves here, so we 32 | # skip building it on macos. 33 | [dependencies.not(os=darwin)] 34 | sqlite3 35 | 36 | [dependencies.os=darwin] 37 | osxfuse 38 | 39 | # TODO: teach getdeps to compile curl on Windows. 40 | # Enabling curl on Windows requires us to find a way to compile libcurl with 41 | # msvc. 42 | [dependencies.not(os=windows)] 43 | libcurl 44 | 45 | [shipit.pathmap] 46 | fbcode/eden/oss = . 47 | fbcode/eden = eden 48 | fbcode/tools/lfs = tools/lfs 49 | 50 | [shipit.strip] 51 | ^fbcode/eden/fs/eden-config\.h$ 52 | ^fbcode/eden/fs/py/eden/config\.py$ 53 | ^fbcode/eden/hg/.*$ 54 | ^fbcode/eden/mononoke/(?!lfs_protocol) 55 | ^fbcode/eden/scm/build/.*$ 56 | ^fbcode/eden/scm/lib/third-party/rust/.*/Cargo.toml$ 57 | ^fbcode/eden/.*/\.cargo/.*$ 58 | /Cargo\.lock$ 59 | \.pyc$ 60 | 61 | [cmake.defines.all(fb=on,os=windows)] 62 | INSTALL_PYTHON_LIB=ON 63 | 64 | [cmake.defines.fb=on] 65 | USE_CARGO_VENDOR=ON 66 | 67 | [depends.environment] 68 | EDEN_VERSION_OVERRIDE 69 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/eden_scm: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = eden_scm 3 | fbsource_path = fbcode/eden 4 | shipit_project = eden 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookexperimental/eden.git 9 | 10 | [build.not(os=windows)] 11 | builder = make 12 | subdir = eden/scm 13 | disable_env_override_pkgconfig = 1 14 | disable_env_override_path = 1 15 | 16 | [build.os=windows] 17 | # For now the biggest blocker is missing "make" on windows, but there are bound 18 | # to be more 19 | builder = nop 20 | 21 | [make.build_args] 22 | getdepsbuild 23 | 24 | [make.install_args] 25 | install-getdeps 26 | 27 | [shipit.pathmap] 28 | fbcode/eden/oss = . 29 | fbcode/eden = eden 30 | fbcode/tools/lfs = tools/lfs 31 | fbcode/fboss/common = common 32 | 33 | [shipit.strip] 34 | ^fbcode/eden/fs/eden-config\.h$ 35 | ^fbcode/eden/fs/py/eden/config\.py$ 36 | ^fbcode/eden/hg/.*$ 37 | ^fbcode/eden/mononoke/(?!lfs_protocol) 38 | ^fbcode/eden/scm/build/.*$ 39 | ^fbcode/eden/scm/lib/third-party/rust/.*/Cargo.toml$ 40 | ^fbcode/eden/.*/\.cargo/.*$ 41 | ^.*/fb/.*$ 42 | /Cargo\.lock$ 43 | \.pyc$ 44 | 45 | [dependencies] 46 | fb303-source 47 | fbthrift 48 | fbthrift-source 49 | openssl 50 | rust-shed 51 | 52 | [dependencies.fb=on] 53 | rust 54 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/eden_scm_lib_edenapi_tools: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = eden_scm_lib_edenapi_tools 3 | fbsource_path = fbcode/eden 4 | shipit_project = eden 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookexperimental/eden.git 9 | 10 | [build] 11 | builder = cargo 12 | 13 | [cargo] 14 | build_doc = true 15 | manifests_to_build = eden/scm/lib/edenapi/tools/make_req/Cargo.toml,eden/scm/lib/edenapi/tools/read_res/Cargo.toml 16 | 17 | [shipit.pathmap] 18 | fbcode/eden/oss = . 19 | fbcode/eden = eden 20 | fbcode/tools/lfs = tools/lfs 21 | fbcode/fboss/common = common 22 | 23 | [shipit.strip] 24 | ^fbcode/eden/fs/eden-config\.h$ 25 | ^fbcode/eden/fs/py/eden/config\.py$ 26 | ^fbcode/eden/hg/.*$ 27 | ^fbcode/eden/mononoke/(?!lfs_protocol) 28 | ^fbcode/eden/scm/build/.*$ 29 | ^fbcode/eden/scm/lib/third-party/rust/.*/Cargo.toml$ 30 | ^fbcode/eden/.*/\.cargo/.*$ 31 | ^.*/fb/.*$ 32 | /Cargo\.lock$ 33 | \.pyc$ 34 | 35 | [dependencies.fb=on] 36 | rust 37 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fatal: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fatal 3 | fbsource_path = fbcode/fatal 4 | shipit_project = fatal 5 | 6 | [git] 7 | repo_url = https://github.com/facebook/fatal.git 8 | 9 | [shipit.pathmap] 10 | fbcode/fatal = . 11 | fbcode/fatal/public_tld = . 12 | 13 | [build] 14 | builder = nop 15 | subdir = . 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fb303: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fb303 3 | fbsource_path = fbcode/fb303 4 | shipit_project = fb303 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookincubator/fb303.git 9 | 10 | [build] 11 | builder = cmake 12 | 13 | [dependencies] 14 | folly 15 | gflags 16 | glog 17 | fbthrift 18 | 19 | [cmake.defines.test=on] 20 | BUILD_TESTS=ON 21 | 22 | [cmake.defines.test=off] 23 | BUILD_TESTS=OFF 24 | 25 | [shipit.pathmap] 26 | fbcode/fb303/github = . 27 | fbcode/fb303 = fb303 28 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fb303-source: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fb303-source 3 | fbsource_path = fbcode/fb303 4 | shipit_project = fb303 5 | shipit_fbcode_builder = false 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/fb303.git 9 | 10 | [build] 11 | builder = nop 12 | 13 | [shipit.pathmap] 14 | fbcode/fb303/github = . 15 | fbcode/fb303 = fb303 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fboss: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fboss 3 | fbsource_path = fbcode/fboss 4 | shipit_project = fboss 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/fboss.git 9 | 10 | [build.os=linux] 11 | builder = cmake 12 | 13 | [build.not(os=linux)] 14 | builder = nop 15 | 16 | [dependencies] 17 | folly 18 | fb303 19 | wangle 20 | fizz 21 | fmt 22 | libsodium 23 | googletest 24 | zstd 25 | fbthrift 26 | iproute2 27 | libmnl 28 | libusb 29 | libcurl 30 | libnl 31 | libsai 32 | OpenNSA 33 | re2 34 | python 35 | 36 | [shipit.pathmap] 37 | fbcode/fboss/github = . 38 | fbcode/fboss/common = common 39 | fbcode/fboss = fboss 40 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fbthrift: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fbthrift 3 | fbsource_path = fbcode/thrift 4 | shipit_project = fbthrift 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/fbthrift.git 9 | 10 | [build] 11 | builder = cmake 12 | 13 | [dependencies] 14 | bison 15 | flex 16 | folly 17 | wangle 18 | fizz 19 | fmt 20 | googletest 21 | libsodium 22 | python-six 23 | zstd 24 | 25 | [shipit.pathmap] 26 | fbcode/thrift/public_tld = . 27 | fbcode/thrift = thrift 28 | 29 | [shipit.strip] 30 | ^fbcode/thrift/thrift-config\.h$ 31 | ^fbcode/thrift/perf/canary.py$ 32 | ^fbcode/thrift/perf/loadtest.py$ 33 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fbthrift-source: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fbthrift-source 3 | fbsource_path = fbcode/thrift 4 | shipit_project = fbthrift 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/fbthrift.git 9 | 10 | [build] 11 | builder = nop 12 | 13 | [shipit.pathmap] 14 | fbcode/thrift/public_tld = . 15 | fbcode/thrift = thrift 16 | 17 | [shipit.strip] 18 | ^fbcode/thrift/thrift-config\.h$ 19 | ^fbcode/thrift/perf/canary.py$ 20 | ^fbcode/thrift/perf/loadtest.py$ 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fbzmq: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fbzmq 3 | fbsource_path = facebook/fbzmq 4 | shipit_project = fbzmq 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/fbzmq.git 9 | 10 | [build.os=linux] 11 | builder = cmake 12 | 13 | [build.not(os=linux)] 14 | # boost.fiber is required and that is not available on macos. 15 | # libzmq doesn't currently build on windows. 16 | builder = nop 17 | 18 | [dependencies] 19 | boost 20 | folly 21 | fbthrift 22 | googletest 23 | libzmq 24 | 25 | [shipit.pathmap] 26 | fbcode/fbzmq = fbzmq 27 | fbcode/fbzmq/public_tld = . 28 | 29 | [shipit.strip] 30 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fizz: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fizz 3 | fbsource_path = fbcode/fizz 4 | shipit_project = fizz 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookincubator/fizz.git 9 | 10 | [build] 11 | builder = cmake 12 | subdir = fizz 13 | 14 | [cmake.defines] 15 | BUILD_EXAMPLES = OFF 16 | 17 | [cmake.defines.test=on] 18 | BUILD_TESTS = ON 19 | 20 | [cmake.defines.all(os=windows, test=on)] 21 | BUILD_TESTS = OFF 22 | 23 | [cmake.defines.test=off] 24 | BUILD_TESTS = OFF 25 | 26 | [dependencies] 27 | folly 28 | libsodium 29 | 30 | [dependencies.all(test=on, not(os=windows))] 31 | googletest_1_8 32 | 33 | [shipit.pathmap] 34 | fbcode/fizz/public_tld = . 35 | fbcode/fizz = fizz 36 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/flex: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = flex 3 | 4 | [rpms] 5 | flex 6 | 7 | [debs] 8 | flex 9 | 10 | [download.not(os=windows)] 11 | url = https://github.com/westes/flex/releases/download/v2.6.4/flex-2.6.4.tar.gz 12 | sha256 = e87aae032bf07c26f85ac0ed3250998c37621d95f8bd748b31f15b33c45ee995 13 | 14 | [download.os=windows] 15 | url = https://github.com/lexxmark/winflexbison/releases/download/v2.5.17/winflexbison-2.5.17.zip 16 | sha256 = 3dc27a16c21b717bcc5de8590b564d4392a0b8577170c058729d067d95ded825 17 | 18 | [build.not(os=windows)] 19 | builder = autoconf 20 | subdir = flex-2.6.4 21 | 22 | [build.os=windows] 23 | builder = nop 24 | 25 | [install.files.os=windows] 26 | data = bin/data 27 | win_flex.exe = bin/flex.exe 28 | 29 | # Moral equivalent to this PR that fixes a crash when bootstrapping flex 30 | # on linux: https://github.com/easybuilders/easybuild-easyconfigs/pull/5792 31 | [autoconf.args.os=linux] 32 | CFLAGS=-D_GNU_SOURCE 33 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/fmt: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = fmt 3 | 4 | [download] 5 | url = https://github.com/fmtlib/fmt/archive/6.1.1.tar.gz 6 | sha256 = bf4e50955943c1773cc57821d6c00f7e2b9e10eb435fafdd66739d36056d504e 7 | 8 | [build] 9 | builder = cmake 10 | subdir = fmt-6.1.1 11 | 12 | [cmake.defines] 13 | FMT_TEST = OFF 14 | FMT_DOC = OFF 15 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/folly: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = folly 3 | fbsource_path = fbcode/folly 4 | shipit_project = folly 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/folly.git 9 | 10 | [build] 11 | builder = cmake 12 | 13 | [dependencies] 14 | gflags 15 | glog 16 | googletest 17 | boost 18 | libevent 19 | double-conversion 20 | fmt 21 | lz4 22 | snappy 23 | zstd 24 | # no openssl or zlib in the linux case, why? 25 | # these are usually installed on the system 26 | # and are the easiest system deps to pull in. 27 | # In the future we want to be able to express 28 | # that a system dep is sufficient in the manifest 29 | # for eg: openssl and zlib, but for now we don't 30 | # have it. 31 | 32 | # macOS doesn't expose the openssl api so we need 33 | # to build our own. 34 | [dependencies.os=darwin] 35 | openssl 36 | 37 | # Windows has neither openssl nor zlib, so we get 38 | # to provide both 39 | [dependencies.os=windows] 40 | openssl 41 | zlib 42 | 43 | [shipit.pathmap] 44 | fbcode/folly/public_tld = . 45 | fbcode/folly = folly 46 | 47 | [shipit.strip] 48 | ^fbcode/folly/folly-config\.h$ 49 | ^fbcode/folly/public_tld/build/facebook_.* 50 | 51 | [cmake.defines] 52 | BUILD_SHARED_LIBS=OFF 53 | 54 | [cmake.defines.test=on] 55 | BUILD_TESTS=ON 56 | 57 | [cmake.defines.test=off] 58 | BUILD_TESTS=OFF 59 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gflags: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gflags 3 | 4 | [download] 5 | url = https://github.com/gflags/gflags/archive/v2.2.2.tar.gz 6 | sha256 = 34af2f15cf7367513b352bdcd2493ab14ce43692d2dcd9dfc499492966c64dcf 7 | 8 | [build] 9 | builder = cmake 10 | subdir = gflags-2.2.2 11 | 12 | [cmake.defines] 13 | BUILD_SHARED_LIBS = ON 14 | BUILD_STATIC_LIBS = ON 15 | #BUILD_gflags_nothreads_LIB = OFF 16 | BUILD_gflags_LIB = ON 17 | 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/git-lfs: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = git-lfs 3 | 4 | [download.os=linux] 5 | url = https://github.com/git-lfs/git-lfs/releases/download/v2.9.1/git-lfs-linux-amd64-v2.9.1.tar.gz 6 | sha256 = 2a8e60cf51ec45aa0f4332aa0521d60ec75c76e485d13ebaeea915b9d70ea466 7 | 8 | [build] 9 | builder = nop 10 | 11 | [install.files] 12 | git-lfs = bin/git-lfs 13 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/glog: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = glog 3 | 4 | [download] 5 | url = https://github.com/google/glog/archive/v0.4.0.tar.gz 6 | sha256 = f28359aeba12f30d73d9e4711ef356dc842886968112162bc73002645139c39c 7 | 8 | [build] 9 | builder = cmake 10 | subdir = glog-0.4.0 11 | 12 | [dependencies] 13 | gflags 14 | 15 | [cmake.defines] 16 | BUILD_SHARED_LIBS=ON 17 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gnu-bash: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gnu-bash 3 | 4 | [download.os=darwin] 5 | url = https://ftp.gnu.org/gnu/bash/bash-5.1-rc1.tar.gz 6 | sha256 = 0b2684eb1990329d499c96decfe2459f3e150deb915b0a9d03cf1be692b1d6d3 7 | 8 | [build.os=darwin] 9 | # The buildin FreeBSD bash on OSX is both outdated and incompatible with the 10 | # modern GNU bash, so for the sake of being cross-platform friendly this 11 | # manifest provides GNU bash. 12 | # NOTE: This is the 5.1-rc1 version, which is almost the same as what Homebrew 13 | # uses (Homebrew installs 5.0 with the 18 patches that in fact make the 5.1-rc1 14 | # version). 15 | builder = autoconf 16 | subdir = bash-5.1-rc1 17 | build_in_src_dir = true 18 | 19 | [build.not(os=darwin)] 20 | builder = nop 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gnu-coreutils: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gnu-coreutils 3 | 4 | [download.os=darwin] 5 | url = https://ftp.gnu.org/gnu/coreutils/coreutils-8.32.tar.gz 6 | sha256 = d5ab07435a74058ab69a2007e838be4f6a90b5635d812c2e26671e3972fca1b8 7 | 8 | [build.os=darwin] 9 | # The buildin FreeBSD version incompatible with the GNU one, so for the sake of 10 | # being cross-platform friendly this manifest provides the GNU version. 11 | builder = autoconf 12 | subdir = coreutils-8.32 13 | 14 | [build.not(os=darwin)] 15 | builder = nop 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gnu-grep: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gnu-grep 3 | 4 | [download.os=darwin] 5 | url = https://ftp.gnu.org/gnu/grep/grep-3.5.tar.gz 6 | sha256 = 9897220992a8fd38a80b70731462defa95f7ff2709b235fb54864ddd011141dd 7 | 8 | [build.os=darwin] 9 | # The buildin FreeBSD version incompatible with the GNU one, so for the sake of 10 | # being cross-platform friendly this manifest provides the GNU version. 11 | builder = autoconf 12 | subdir = grep-3.5 13 | 14 | [build.not(os=darwin)] 15 | builder = nop 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gnu-sed: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gnu-sed 3 | 4 | [download.os=darwin] 5 | url = https://ftp.gnu.org/gnu/sed/sed-4.8.tar.gz 6 | sha256 = 53cf3e14c71f3a149f29d13a0da64120b3c1d3334fba39c4af3e520be053982a 7 | 8 | [build.os=darwin] 9 | # The buildin FreeBSD version incompatible with the GNU one, so for the sake of 10 | # being cross-platform friendly this manifest provides the GNU version. 11 | builder = autoconf 12 | subdir = sed-4.8 13 | 14 | [build.not(os=darwin)] 15 | builder = nop 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/googletest: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = googletest 3 | 4 | [download] 5 | url = https://github.com/google/googletest/archive/release-1.10.0.tar.gz 6 | sha256 = 9dc9157a9a1551ec7a7e43daea9a694a0bb5fb8bec81235d8a1e6ef64c716dcb 7 | 8 | [build] 9 | builder = cmake 10 | subdir = googletest-release-1.10.0 11 | 12 | [cmake.defines] 13 | # Everything else defaults to the shared runtime, so tell gtest that 14 | # it should not use its choice of the static runtime 15 | gtest_force_shared_crt=ON 16 | 17 | [cmake.defines.os=windows] 18 | BUILD_SHARED_LIBS=ON 19 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/googletest_1_8: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = googletest_1_8 3 | 4 | [download] 5 | url = https://github.com/google/googletest/archive/release-1.8.0.tar.gz 6 | sha256 = 58a6f4277ca2bc8565222b3bbd58a177609e9c488e8a72649359ba51450db7d8 7 | 8 | [build] 9 | builder = cmake 10 | subdir = googletest-release-1.8.0 11 | 12 | [cmake.defines] 13 | # Everything else defaults to the shared runtime, so tell gtest that 14 | # it should not use its choice of the static runtime 15 | gtest_force_shared_crt=ON 16 | 17 | [cmake.defines.os=windows] 18 | BUILD_SHARED_LIBS=ON 19 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/gperf: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = gperf 3 | 4 | [download] 5 | url = http://ftp.gnu.org/pub/gnu/gperf/gperf-3.1.tar.gz 6 | sha256 = 588546b945bba4b70b6a3a616e80b4ab466e3f33024a352fc2198112cdbb3ae2 7 | 8 | [build.not(os=windows)] 9 | builder = autoconf 10 | subdir = gperf-3.1 11 | 12 | [build.os=windows] 13 | builder = nop 14 | 15 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/iproute2: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = iproute2 3 | 4 | [download] 5 | url = https://mirrors.edge.kernel.org/pub/linux/utils/net/iproute2/iproute2-4.12.0.tar.gz 6 | sha256 = 46612a1e2d01bb31932557bccdb1b8618cae9a439dfffc08ef35ed8e197f14ce 7 | 8 | [build.os=linux] 9 | builder = iproute2 10 | subdir = iproute2-4.12.0 11 | 12 | [build.not(os=linux)] 13 | builder = nop 14 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/jq: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = jq 3 | 4 | [rpms] 5 | jq 6 | 7 | [debs] 8 | jq 9 | 10 | [download.not(os=windows)] 11 | url = https://github.com/stedolan/jq/releases/download/jq-1.5/jq-1.5.tar.gz 12 | sha256 = c4d2bfec6436341113419debf479d833692cc5cdab7eb0326b5a4d4fbe9f493c 13 | 14 | [build.not(os=windows)] 15 | builder = autoconf 16 | subdir = jq-1.5 17 | 18 | [build.os=windows] 19 | builder = nop 20 | 21 | [autoconf.args] 22 | # This argument turns off some developers tool and it is recommended in jq's 23 | # README 24 | --disable-maintainer-mode 25 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/katran: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = katran 3 | fbsource_path = fbcode/katran 4 | shipit_project = katran 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookincubator/katran.git 9 | 10 | [build.not(os=linux)] 11 | builder = nop 12 | 13 | [build.os=linux] 14 | builder = cmake 15 | subdir = . 16 | 17 | [cmake.defines.test=on] 18 | BUILD_TESTS=ON 19 | 20 | [cmake.defines.test=off] 21 | BUILD_TESTS=OFF 22 | 23 | 24 | [dependencies] 25 | folly 26 | fizz 27 | libbpf_0_2_0_beta 28 | libmnl 29 | zlib 30 | googletest 31 | 32 | 33 | [shipit.pathmap] 34 | fbcode/katran/public_root = . 35 | fbcode/katran = katran 36 | 37 | [shipit.strip] 38 | ^fbcode/katran/facebook 39 | ^fbcode/katran/OSS_SYNC 40 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libbpf: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libbpf 3 | 4 | [download] 5 | url = https://github.com/libbpf/libbpf/archive/v0.1.1.tar.gz 6 | sha256 = 3fd271cf65b39bf38432b29d9dd2f694600c97dab0928baee419a65b5db4e598 7 | 8 | # BPF only builds on linux, so make it a NOP on other platforms 9 | [build.not(os=linux)] 10 | builder = nop 11 | 12 | [build.os=linux] 13 | builder = make 14 | subdir = libbpf-0.1.1/src 15 | 16 | [make.build_args] 17 | BUILD_STATIC_ONLY=y 18 | 19 | # libbpf-0.1.1 requires uapi headers >= 5.8 20 | [make.install_args] 21 | install 22 | install_uapi_headers 23 | BUILD_STATIC_ONLY=y 24 | 25 | [dependencies] 26 | libelf 27 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libbpf_0_2_0_beta: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libbpf_0_2_0_beta 3 | 4 | [download] 5 | url = https://github.com/libbpf/libbpf/archive/b6dd2f2.tar.gz 6 | sha256 = 8db9dca90f5c445ef2362e3c6a00f3d6c4bf36e8782f8e27704109c78e541497 7 | 8 | # BPF only builds on linux, so make it a NOP on other platforms 9 | [build.not(os=linux)] 10 | builder = nop 11 | 12 | [build.os=linux] 13 | builder = make 14 | subdir = libbpf-b6dd2f2b7df4d3bd35d64aaf521d9ad18d766f53/src 15 | 16 | [make.build_args] 17 | BUILD_STATIC_ONLY=y 18 | 19 | # libbpf now requires uapi headers >= 5.8 20 | [make.install_args] 21 | install 22 | install_uapi_headers 23 | BUILD_STATIC_ONLY=y 24 | 25 | [dependencies] 26 | libelf 27 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libcurl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libcurl 3 | 4 | [rpms] 5 | libcurl-devel 6 | libcurl 7 | 8 | [debs] 9 | libcurl4-openssl-dev 10 | 11 | [download] 12 | url = https://curl.haxx.se/download/curl-7.65.1.tar.gz 13 | sha256 = 821aeb78421375f70e55381c9ad2474bf279fc454b791b7e95fc83562951c690 14 | 15 | [dependencies] 16 | nghttp2 17 | 18 | # We use system OpenSSL on Linux (see folly's manifest for details) 19 | [dependencies.not(os=linux)] 20 | openssl 21 | 22 | [build.not(os=windows)] 23 | builder = autoconf 24 | subdir = curl-7.65.1 25 | 26 | [autoconf.args] 27 | # fboss (which added the libcurl dep) doesn't need ldap so it is disabled here. 28 | # if someone in the future wants to add ldap for something else, it won't hurt 29 | # fboss. However, that would require adding an ldap manifest. 30 | # 31 | # For the same reason, we disable libssh2 and libidn2 which aren't really used 32 | # but would require adding manifests if we don't disable them. 33 | --disable-ldap 34 | --without-libssh2 35 | --without-libidn2 36 | 37 | [build.os=windows] 38 | builder = cmake 39 | subdir = curl-7.65.1 40 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libelf: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libelf 3 | 4 | [rpms] 5 | elfutils-libelf-devel-static 6 | 7 | [debs] 8 | libelf-dev 9 | 10 | [download] 11 | url = https://ftp.osuosl.org/pub/blfs/conglomeration/libelf/libelf-0.8.13.tar.gz 12 | sha256 = 591a9b4ec81c1f2042a97aa60564e0cb79d041c52faa7416acb38bc95bd2c76d 13 | 14 | # libelf only makes sense on linux, so make it a NOP on other platforms 15 | [build.not(os=linux)] 16 | builder = nop 17 | 18 | [build.os=linux] 19 | builder = autoconf 20 | subdir = libelf-0.8.13 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libevent: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libevent 3 | 4 | [rpms] 5 | libevent-devel 6 | 7 | [debs] 8 | libevent-dev 9 | 10 | # Note that the CMakeLists.txt file is present only in 11 | # git repo and not in the release tarball, so take care 12 | # to use the github generated source tarball rather than 13 | # the explicitly uploaded source tarball 14 | [download] 15 | url = https://github.com/libevent/libevent/archive/release-2.1.8-stable.tar.gz 16 | sha256 = 316ddb401745ac5d222d7c529ef1eada12f58f6376a66c1118eee803cb70f83d 17 | 18 | [build] 19 | builder = cmake 20 | subdir = libevent-release-2.1.8-stable 21 | 22 | [cmake.defines] 23 | EVENT__DISABLE_TESTS = ON 24 | EVENT__DISABLE_BENCHMARK = ON 25 | EVENT__DISABLE_SAMPLES = ON 26 | EVENT__DISABLE_REGRESS = ON 27 | 28 | [dependencies.not(os=linux)] 29 | openssl 30 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libgit2: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libgit2 3 | 4 | [rpms] 5 | libgit2-devel 6 | 7 | [debs] 8 | libgit2-dev 9 | 10 | [download] 11 | url = https://github.com/libgit2/libgit2/archive/v0.28.1.tar.gz 12 | sha256 = 0ca11048795b0d6338f2e57717370208c2c97ad66c6d5eac0c97a8827d13936b 13 | 14 | [build] 15 | builder = cmake 16 | subdir = libgit2-0.28.1 17 | 18 | [cmake.defines] 19 | # Could turn this on if we also wanted to add a manifest for libssh2 20 | USE_SSH = OFF 21 | BUILD_CLAR = OFF 22 | # Have to build shared to work around annoying problems with cmake 23 | # mis-parsing the frameworks required to link this on macos :-/ 24 | BUILD_SHARED_LIBS = ON 25 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libmnl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libmnl 3 | 4 | [rpms] 5 | libmnl-devel 6 | libmnl-static 7 | 8 | [debs] 9 | libmnl-dev 10 | 11 | [download] 12 | url = http://www.lg.ps.pl/mirrors/ftp.netfilter.org/libmnl/libmnl-1.0.4.tar.bz2 13 | sha256 = 171f89699f286a5854b72b91d06e8f8e3683064c5901fb09d954a9ab6f551f81 14 | 15 | [build.os=linux] 16 | builder = autoconf 17 | subdir = libmnl-1.0.4 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libnl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libnl 3 | 4 | [rpms] 5 | libnl3-devel 6 | libnl3 7 | 8 | [debs] 9 | libnl-3-dev 10 | 11 | [download] 12 | url = https://www.infradead.org/~tgr/libnl/files/libnl-3.2.25.tar.gz 13 | sha256 = 8beb7590674957b931de6b7f81c530b85dc7c1ad8fbda015398bc1e8d1ce8ec5 14 | 15 | [build.os=linux] 16 | builder = autoconf 17 | subdir = libnl-3.2.25 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libsai: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libsai 3 | 4 | [download] 5 | url = https://github.com/opencomputeproject/SAI/archive/v1.6.3.tar.gz 6 | sha256 = ff09308fea187885b8f4d86446c5e0c097e801e8fe98de1b5e25cdc80d52e3cb 7 | 8 | [build] 9 | builder = nop 10 | subdir = SAI-1.6.3 11 | 12 | [install.files] 13 | inc = include 14 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libsodium: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libsodium 3 | 4 | [rpms] 5 | libsodium-devel 6 | libsodium-static 7 | 8 | [debs] 9 | libsodium-dev 10 | 11 | [download.not(os=windows)] 12 | url = https://github.com/jedisct1/libsodium/releases/download/1.0.17/libsodium-1.0.17.tar.gz 13 | sha256 = 0cc3dae33e642cc187b5ceb467e0ad0e1b51dcba577de1190e9ffa17766ac2b1 14 | 15 | [build.not(os=windows)] 16 | builder = autoconf 17 | subdir = libsodium-1.0.17 18 | 19 | [download.os=windows] 20 | url = https://download.libsodium.org/libsodium/releases/libsodium-1.0.17-msvc.zip 21 | sha256 = f0f32ad8ebd76eee99bb039f843f583f2babca5288a8c26a7261db9694c11467 22 | 23 | [build.os=windows] 24 | builder = nop 25 | 26 | [install.files.os=windows] 27 | x64/Release/v141/dynamic/libsodium.dll = bin/libsodium.dll 28 | x64/Release/v141/dynamic/libsodium.lib = lib/libsodium.lib 29 | x64/Release/v141/dynamic/libsodium.exp = lib/libsodium.exp 30 | x64/Release/v141/dynamic/libsodium.pdb = lib/libsodium.pdb 31 | include = include 32 | 33 | [autoconf.args] 34 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libtool: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libtool 3 | 4 | [rpms] 5 | libtool 6 | 7 | [debs] 8 | libtool 9 | 10 | [download] 11 | url = http://ftp.gnu.org/gnu/libtool/libtool-2.4.6.tar.gz 12 | sha256 = e3bd4d5d3d025a36c21dd6af7ea818a2afcd4dfc1ea5a17b39d7854bcd0c06e3 13 | 14 | [build] 15 | builder = autoconf 16 | subdir = libtool-2.4.6 17 | 18 | [dependencies] 19 | automake 20 | 21 | [autoconf.args] 22 | --enable-ltdl-install 23 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libusb: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libusb 3 | 4 | [rpms] 5 | libusb-devel 6 | libusb 7 | 8 | [debs] 9 | libusb-1.0-0-dev 10 | 11 | [download] 12 | url = https://github.com/libusb/libusb/releases/download/v1.0.22/libusb-1.0.22.tar.bz2 13 | sha256 = 75aeb9d59a4fdb800d329a545c2e6799f732362193b465ea198f2aa275518157 14 | 15 | [build.os=linux] 16 | builder = autoconf 17 | subdir = libusb-1.0.22 18 | 19 | [autoconf.args] 20 | # fboss (which added the libusb dep) doesn't need udev so it is disabled here. 21 | # if someone in the future wants to add udev for something else, it won't hurt 22 | # fboss. 23 | --disable-udev 24 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/libzmq: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = libzmq 3 | 4 | [rpms] 5 | zeromq-devel 6 | zeromq 7 | 8 | [debs] 9 | libzmq3-dev 10 | 11 | [download] 12 | url = https://github.com/zeromq/libzmq/releases/download/v4.3.1/zeromq-4.3.1.tar.gz 13 | sha256 = bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d835cd21eb 14 | 15 | 16 | [build] 17 | builder = autoconf 18 | subdir = zeromq-4.3.1 19 | 20 | [autoconf.args] 21 | 22 | [dependencies] 23 | autoconf 24 | libtool 25 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/lz4: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = lz4 3 | 4 | [rpms] 5 | lz4-devel 6 | lz4-static 7 | 8 | [debs] 9 | liblz4-dev 10 | 11 | [download] 12 | url = https://github.com/lz4/lz4/archive/v1.8.3.tar.gz 13 | sha256 = 33af5936ac06536805f9745e0b6d61da606a1f8b4cc5c04dd3cbaca3b9b4fc43 14 | 15 | [build] 16 | builder = cmake 17 | subdir = lz4-1.8.3/contrib/cmake_unofficial 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/mononoke: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = mononoke 3 | fbsource_path = fbcode/eden 4 | shipit_project = eden 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookexperimental/eden.git 9 | 10 | [build.not(os=windows)] 11 | builder = cargo 12 | 13 | [build.os=windows] 14 | # building Mononoke on windows is not supported 15 | builder = nop 16 | 17 | [cargo] 18 | build_doc = true 19 | workspace_dir = eden/mononoke 20 | 21 | [shipit.pathmap] 22 | fbcode/configerator/structs/scm/mononoke/public_autocargo = configerator/structs/scm/mononoke 23 | fbcode/configerator/structs/scm/mononoke = configerator/structs/scm/mononoke 24 | fbcode/eden/oss = . 25 | fbcode/eden = eden 26 | fbcode/eden/mononoke/public_autocargo = eden/mononoke 27 | fbcode/tools/lfs = tools/lfs 28 | tools/rust/ossconfigs = . 29 | 30 | [shipit.strip] 31 | # strip all code unrelated to mononoke to prevent triggering unnecessary checks 32 | ^fbcode/eden/(?!mononoke|scm/lib/xdiff.*)/.*$ 33 | ^fbcode/eden/scm/lib/third-party/rust/.*/Cargo.toml$ 34 | ^fbcode/eden/mononoke/Cargo\.toml$ 35 | ^fbcode/eden/mononoke/(?!public_autocargo).+/Cargo\.toml$ 36 | ^fbcode/configerator/structs/scm/mononoke/(?!public_autocargo).+/Cargo\.toml$ 37 | ^.*/facebook/.*$ 38 | 39 | [dependencies] 40 | fbthrift-source 41 | rust-shed 42 | 43 | [dependencies.fb=on] 44 | rust 45 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/mononoke_integration: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = mononoke_integration 3 | fbsource_path = fbcode/eden 4 | shipit_project = eden 5 | shipit_fbcode_builder = true 6 | 7 | [build.not(os=windows)] 8 | builder = make 9 | subdir = eden/mononoke/tests/integration 10 | 11 | [build.os=windows] 12 | # building Mononoke on windows is not supported 13 | builder = nop 14 | 15 | [make.build_args] 16 | build-getdeps 17 | 18 | [make.install_args] 19 | install-getdeps 20 | 21 | [make.test_args] 22 | test-getdeps 23 | 24 | [shipit.pathmap] 25 | fbcode/eden/mononoke/tests/integration = eden/mononoke/tests/integration 26 | 27 | [shipit.strip] 28 | ^.*/facebook/.*$ 29 | 30 | [dependencies] 31 | eden_scm 32 | eden_scm_lib_edenapi_tools 33 | jq 34 | mononoke 35 | nmap 36 | python-click 37 | python-dulwich 38 | tree 39 | 40 | [dependencies.os=linux] 41 | sqlite3-bin 42 | 43 | [dependencies.os=darwin] 44 | gnu-bash 45 | gnu-coreutils 46 | gnu-grep 47 | gnu-sed 48 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/mvfst: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = mvfst 3 | fbsource_path = fbcode/quic 4 | shipit_project = mvfst 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookincubator/mvfst.git 9 | 10 | [build] 11 | builder = cmake 12 | subdir = . 13 | 14 | [cmake.defines.test=on] 15 | BUILD_TESTS = ON 16 | 17 | [cmake.defines.all(os=windows, test=on)] 18 | BUILD_TESTS = OFF 19 | 20 | [cmake.defines.test=off] 21 | BUILD_TESTS = OFF 22 | 23 | [dependencies] 24 | folly 25 | fizz 26 | 27 | [dependencies.all(test=on, not(os=windows))] 28 | googletest_1_8 29 | 30 | [shipit.pathmap] 31 | fbcode/quic/public_root = . 32 | fbcode/quic = quic 33 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/nghttp2: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = nghttp2 3 | 4 | [rpms] 5 | libnghttp2-devel 6 | libnghttp2 7 | 8 | [debs] 9 | libnghttp2-dev 10 | 11 | [download] 12 | url = https://github.com/nghttp2/nghttp2/releases/download/v1.39.2/nghttp2-1.39.2.tar.gz 13 | sha256 = fc820a305e2f410fade1a3260f09229f15c0494fc089b0100312cd64a33a38c0 14 | 15 | [build] 16 | builder = autoconf 17 | subdir = nghttp2-1.39.2 18 | 19 | [autoconf.args] 20 | --enable-lib-only 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/ninja: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = ninja 3 | 4 | [rpms] 5 | ninja-build 6 | 7 | [debs] 8 | ninja-build 9 | 10 | [download.os=windows] 11 | url = https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-win.zip 12 | sha256 = 2d70010633ddaacc3af4ffbd21e22fae90d158674a09e132e06424ba3ab036e9 13 | 14 | [build.not(os=linux)] 15 | builder = nop 16 | 17 | [install.files.os=windows] 18 | ninja.exe = bin/ninja.exe 19 | 20 | [download.os=darwin] 21 | url = https://github.com/ninja-build/ninja/releases/download/v1.9.0/ninja-mac.zip 22 | sha256 = 26d32a79f786cca1004750f59e545199bf110e21e300d3c2424c1fddd78f28ab 23 | 24 | [download.os=linux] 25 | url = https://github.com/ninja-build/ninja/archive/v1.9.0.tar.gz 26 | sha256 = 5d7ec75828f8d3fd1a0c2f31b5b0cea780cdfe1031359228c428c1a48bfcd5b9 27 | 28 | [install.files.os=darwin] 29 | ninja = bin/ninja 30 | 31 | [build.os=linux] 32 | builder = ninja_bootstrap 33 | subdir = ninja-1.9.0 34 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/nmap: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = nmap 3 | 4 | [rpms] 5 | nmap 6 | 7 | [debs] 8 | nmap 9 | 10 | [download.not(os=windows)] 11 | url = https://api.github.com/repos/nmap/nmap/tarball/ef8213a36c2e89233c806753a57b5cd473605408 12 | sha256 = eda39e5a8ef4964fac7db16abf91cc11ff568eac0fa2d680b0bfa33b0ed71f4a 13 | 14 | [build.not(os=windows)] 15 | builder = autoconf 16 | subdir = nmap-nmap-ef8213a 17 | build_in_src_dir = true 18 | 19 | [build.os=windows] 20 | builder = nop 21 | 22 | [autoconf.args] 23 | # Without this option the build was filing to find some third party libraries 24 | # that we don't need 25 | enable_rdma=no 26 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/openr: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = openr 3 | fbsource_path = facebook/openr 4 | shipit_project = openr 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/openr.git 9 | 10 | [build.os=linux] 11 | builder = cmake 12 | 13 | [build.not(os=linux)] 14 | # boost.fiber is required and that is not available on macos. 15 | # libzmq doesn't currently build on windows. 16 | builder = nop 17 | 18 | [dependencies] 19 | boost 20 | fb303 21 | fbthrift 22 | fbzmq 23 | folly 24 | googletest 25 | re2 26 | 27 | [cmake.defines.test=on] 28 | BUILD_TESTS=ON 29 | ADD_ROOT_TESTS=OFF 30 | 31 | [cmake.defines.test=off] 32 | BUILD_TESTS=OFF 33 | 34 | 35 | [shipit.pathmap] 36 | fbcode/openr = openr 37 | fbcode/openr/public_tld = . 38 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/openssl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = openssl 3 | 4 | [rpms] 5 | openssl-devel 6 | openssl 7 | 8 | [debs] 9 | libssl-dev 10 | 11 | [download] 12 | url = https://www.openssl.org/source/openssl-1.1.1f.tar.gz 13 | sha256 = 186c6bfe6ecfba7a5b48c47f8a1673d0f3b0e5ba2e25602dd23b629975da3f35 14 | 15 | [build] 16 | builder = openssl 17 | subdir = openssl-1.1.1f 18 | 19 | [dependencies.os=windows] 20 | perl 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/osxfuse: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = osxfuse 3 | 4 | [download] 5 | url = https://github.com/osxfuse/osxfuse/archive/osxfuse-3.8.3.tar.gz 6 | sha256 = 93bab6731bdfe8dc1ef069483437270ce7fe5a370f933d40d8d0ef09ba846c0c 7 | 8 | [build] 9 | builder = nop 10 | 11 | [install.files] 12 | osxfuse-osxfuse-3.8.3/common = include 13 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/patchelf: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = patchelf 3 | 4 | [rpms] 5 | patchelf 6 | 7 | [debs] 8 | patchelf 9 | 10 | [download] 11 | url = https://github.com/NixOS/patchelf/archive/0.10.tar.gz 12 | sha256 = b3cb6bdedcef5607ce34a350cf0b182eb979f8f7bc31eae55a93a70a3f020d13 13 | 14 | [build] 15 | builder = autoconf 16 | subdir = patchelf-0.10 17 | 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/pcre: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = pcre 3 | 4 | [rpms] 5 | pcre-devel 6 | pcre-static 7 | 8 | [debs] 9 | libpcre3-dev 10 | 11 | [download] 12 | url = https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz 13 | sha256 = 0b8e7465dc5e98c757cc3650a20a7843ee4c3edf50aaf60bb33fd879690d2c73 14 | 15 | [build] 16 | builder = cmake 17 | subdir = pcre-8.43 18 | 19 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/perl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = perl 3 | 4 | [download.os=windows] 5 | url = http://strawberryperl.com/download/5.28.1.1/strawberry-perl-5.28.1.1-64bit-portable.zip 6 | sha256 = 935c95ba096fa11c4e1b5188732e3832d330a2a79e9882ab7ba8460ddbca810d 7 | 8 | [build.os=windows] 9 | builder = nop 10 | subdir = perl 11 | 12 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/pexpect: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = pexpect 3 | 4 | [download] 5 | url = https://files.pythonhosted.org/packages/0e/3e/377007e3f36ec42f1b84ec322ee12141a9e10d808312e5738f52f80a232c/pexpect-4.7.0-py2.py3-none-any.whl 6 | sha256 = 2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1 7 | 8 | [build] 9 | builder = python-wheel 10 | 11 | [dependencies] 12 | python-ptyprocess 13 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/proxygen: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = proxygen 3 | fbsource_path = fbcode/proxygen 4 | shipit_project = proxygen 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/proxygen.git 9 | 10 | [build.os=windows] 11 | builder = nop 12 | 13 | [build] 14 | builder = cmake 15 | subdir = . 16 | 17 | [cmake.defines] 18 | BUILD_QUIC = ON 19 | 20 | [cmake.defines.test=on] 21 | BUILD_TESTS = ON 22 | 23 | [cmake.defines.test=off] 24 | BUILD_TESTS = OFF 25 | 26 | [dependencies] 27 | zlib 28 | gperf 29 | folly 30 | fizz 31 | wangle 32 | mvfst 33 | 34 | [dependencies.test=on] 35 | googletest_1_8 36 | 37 | [shipit.pathmap] 38 | fbcode/proxygen/public_tld = . 39 | fbcode/proxygen = proxygen 40 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python 3 | 4 | [rpms] 5 | python3 6 | python3-devel 7 | 8 | [debs] 9 | python3-all-dev 10 | 11 | [download.os=linux] 12 | url = https://www.python.org/ftp/python/3.7.6/Python-3.7.6.tgz 13 | sha256 = aeee681c235ad336af116f08ab6563361a0c81c537072c1b309d6e4050aa2114 14 | 15 | [build.os=linux] 16 | builder = autoconf 17 | subdir = Python-3.7.6 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python-click: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python-click 3 | 4 | [download] 5 | url = https://files.pythonhosted.org/packages/d2/3d/fa76db83bf75c4f8d338c2fd15c8d33fdd7ad23a9b5e57eb6c5de26b430e/click-7.1.2-py2.py3-none-any.whl 6 | sha256 = dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc 7 | 8 | [build] 9 | builder = python-wheel 10 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python-dulwich: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python-dulwich 3 | 4 | # The below links point to custom github forks of project dulwich, because the 5 | # 0.18.6 version didn't have an official rollout of wheel packages. 6 | 7 | [download.os=linux] 8 | url = https://github.com/lukaspiatkowski/dulwich/releases/download/dulwich-0.18.6-wheel/dulwich-0.18.6-cp36-cp36m-linux_x86_64.whl 9 | sha256 = e96f545f3d003e67236785473caaba2c368e531ea85fd508a3bd016ebac3a6d8 10 | 11 | [download.os=darwin] 12 | url = https://github.com/lukaspiatkowski/dulwich/releases/download/dulwich-0.18.6-wheel/dulwich-0.18.6-cp37-cp37m-macosx_10_14_x86_64.whl 13 | sha256 = 8373652056284ad40ea5220b659b3489b0a91f25536322345a3e4b5d29069308 14 | 15 | [build.not(os=windows)] 16 | builder = python-wheel 17 | 18 | [build.os=windows] 19 | builder = nop 20 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python-ptyprocess: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python-ptyprocess 3 | 4 | [download] 5 | url = https://files.pythonhosted.org/packages/d1/29/605c2cc68a9992d18dada28206eeada56ea4bd07a239669da41674648b6f/ptyprocess-0.6.0-py2.py3-none-any.whl 6 | sha256 = d7cc528d76e76342423ca640335bd3633420dc1366f258cb31d05e865ef5ca1f 7 | 8 | [build] 9 | builder = python-wheel 10 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python-six: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python-six 3 | 4 | [download] 5 | url = https://files.pythonhosted.org/packages/73/fb/00a976f728d0d1fecfe898238ce23f502a721c0ac0ecfedb80e0d88c64e9/six-1.12.0-py2.py3-none-any.whl 6 | sha256 = 3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c 7 | 8 | [build] 9 | builder = python-wheel 10 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/python-toml: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = python-toml 3 | 4 | [download] 5 | url = https://files.pythonhosted.org/packages/a2/12/ced7105d2de62fa7c8fb5fce92cc4ce66b57c95fb875e9318dba7f8c5db0/toml-0.10.0-py2.py3-none-any.whl 6 | sha256 = 235682dd292d5899d361a811df37e04a8828a5b1da3115886b73cf81ebc9100e 7 | 8 | [build] 9 | builder = python-wheel 10 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/re2: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = re2 3 | 4 | [rpms] 5 | re2 6 | re2-devel 7 | 8 | [debs] 9 | libre2-dev 10 | 11 | [download] 12 | url = https://github.com/google/re2/archive/2019-06-01.tar.gz 13 | sha256 = 02b7d73126bd18e9fbfe5d6375a8bb13fadaf8e99e48cbb062e4500fc18e8e2e 14 | 15 | [build] 16 | builder = cmake 17 | subdir = re2-2019-06-01 18 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/rocksdb: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = rocksdb 3 | 4 | [download] 5 | url = https://github.com/facebook/rocksdb/archive/v6.8.1.tar.gz 6 | sha256 = ca192a06ed3bcb9f09060add7e9d0daee1ae7a8705a3d5ecbe41867c5e2796a2 7 | 8 | [dependencies] 9 | lz4 10 | snappy 11 | 12 | [build] 13 | builder = cmake 14 | subdir = rocksdb-6.8.1 15 | 16 | [cmake.defines] 17 | WITH_SNAPPY=ON 18 | WITH_LZ4=ON 19 | WITH_TESTS=OFF 20 | WITH_BENCHMARK_TOOLS=OFF 21 | # We get relocation errors with the static gflags lib, 22 | # and there's no clear way to make it pick the shared gflags 23 | # so just turn it off. 24 | WITH_GFLAGS=OFF 25 | # mac pro machines don't have some of the newer features that 26 | # rocksdb enables by default; ask it to disable their use even 27 | # when building on new hardware 28 | PORTABLE = ON 29 | # Disable the use of -Werror 30 | FAIL_ON_WARNINGS = OFF 31 | 32 | [cmake.defines.os=windows] 33 | ROCKSDB_INSTALL_ON_WINDOWS=ON 34 | # RocksDB hard codes the paths to the snappy libs to something 35 | # that doesn't exist; ignoring the usual cmake rules. As a result, 36 | # we can't build it with snappy without either patching rocksdb or 37 | # without introducing more complex logic to the build system to 38 | # connect the snappy build outputs to rocksdb's custom logic here. 39 | # Let's just turn it off on windows. 40 | WITH_SNAPPY=OFF 41 | WITH_LZ4=OFF 42 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/rust-shed: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = rust-shed 3 | fbsource_path = fbcode/common/rust/shed 4 | shipit_project = rust-shed 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebookexperimental/rust-shed.git 9 | 10 | [build] 11 | builder = cargo 12 | 13 | [cargo] 14 | build_doc = true 15 | workspace_dir = 16 | 17 | [shipit.pathmap] 18 | fbcode/common/rust/shed = shed 19 | fbcode/common/rust/shed/public_autocargo = shed 20 | fbcode/common/rust/shed/public_tld = . 21 | tools/rust/ossconfigs = . 22 | 23 | [shipit.strip] 24 | ^fbcode/common/rust/shed/(?!public_autocargo|public_tld).+/Cargo\.toml$ 25 | 26 | [dependencies] 27 | fbthrift 28 | # macOS doesn't expose the openssl api so we need to build our own. 29 | # Windows doesn't have openssl and Linux might contain an old version, 30 | # so we get to provide it 31 | openssl 32 | 33 | [dependencies.fb=on] 34 | rust 35 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/snappy: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = snappy 3 | 4 | [rpms] 5 | snappy 6 | snappy-devel 7 | 8 | [debs] 9 | libsnappy-dev 10 | 11 | [download] 12 | url = https://github.com/google/snappy/archive/1.1.7.tar.gz 13 | sha256 = 3dfa02e873ff51a11ee02b9ca391807f0c8ea0529a4924afa645fbf97163f9d4 14 | 15 | [build] 16 | builder = cmake 17 | subdir = snappy-1.1.7 18 | 19 | [cmake.defines] 20 | SNAPPY_BUILD_TESTS = OFF 21 | 22 | # Avoid problems like `relocation R_X86_64_PC32 against symbol` on ELF systems 23 | # when linking rocksdb, which builds PIC even when building a static lib 24 | [cmake.defines.os=linux] 25 | BUILD_SHARED_LIBS = ON 26 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/sqlite3: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = sqlite3 3 | 4 | [rpms] 5 | sqlite-devel 6 | sqlite-libs 7 | 8 | [debs] 9 | libsqlite3-dev 10 | 11 | [download] 12 | url = https://sqlite.org/2019/sqlite-amalgamation-3280000.zip 13 | sha256 = d02fc4e95cfef672b45052e221617a050b7f2e20103661cda88387349a9b1327 14 | 15 | [dependencies] 16 | cmake 17 | ninja 18 | 19 | [build] 20 | builder = sqlite 21 | subdir = sqlite-amalgamation-3280000 22 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/sqlite3-bin: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = sqlite3-bin 3 | 4 | [rpms] 5 | sqlite 6 | 7 | [debs] 8 | sqlite3 9 | 10 | [download.os=linux] 11 | url = https://github.com/sqlite/sqlite/archive/version-3.33.0.tar.gz 12 | sha256 = 48e5f989eefe9af0ac758096f82ead0f3c7b58118ac17cc5810495bd5084a331 13 | 14 | [build.os=linux] 15 | builder = autoconf 16 | subdir = sqlite-version-3.33.0 17 | 18 | [build.not(os=linux)] 19 | # MacOS comes with sqlite3 preinstalled and don't need Windows here 20 | builder = nop 21 | 22 | [dependencies.os=linux] 23 | tcl 24 | 25 | [autoconf.args] 26 | # This flag disabled tcl as a runtime library used for some functionality, 27 | # but tcl is still a required dependency as it is used by the build files 28 | --disable-tcl 29 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/tcl: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = tcl 3 | 4 | [rpms] 5 | tcl 6 | 7 | [debs] 8 | tcl 9 | 10 | [download] 11 | url = https://github.com/tcltk/tcl/archive/core-8-7a3.tar.gz 12 | sha256 = 22d748f0c9652f3ecc195fed3f24a1b6eea8d449003085e6651197951528982e 13 | 14 | [build.os=linux] 15 | builder = autoconf 16 | subdir = tcl-core-8-7a3/unix 17 | 18 | [build.not(os=linux)] 19 | # This is for sqlite3 on Linux for now 20 | builder = nop 21 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/tree: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = tree 3 | 4 | [rpms] 5 | tree 6 | 7 | [debs] 8 | tree 9 | 10 | [download.os=linux] 11 | url = https://salsa.debian.org/debian/tree-packaging/-/archive/debian/1.8.0-1/tree-packaging-debian-1.8.0-1.tar.gz 12 | sha256 = a841eee1d52bfd64a48f54caab9937b9bd92935055c48885c4ab1ae4dab7fae5 13 | 14 | [download.os=darwin] 15 | # The official package of tree source requires users of non-Linux platform to 16 | # comment/uncomment certain lines in the Makefile to build for their platform. 17 | # Besauce getdeps.py doesn't have that functionality we just use this custom 18 | # fork of tree which has proper lines uncommented for a OSX build 19 | url = https://github.com/lukaspiatkowski/tree-command/archive/debian/1.8.0-1-macos.tar.gz 20 | sha256 = 9cbe889553d95cf5a2791dd0743795d46a3c092c5bba691769c0e5c52e11229e 21 | 22 | [build.os=linux] 23 | builder = make 24 | subdir = tree-packaging-debian-1.8.0-1 25 | 26 | [build.os=darwin] 27 | builder = make 28 | subdir = tree-command-debian-1.8.0-1-macos 29 | 30 | [build.os=windows] 31 | builder = nop 32 | 33 | [make.install_args] 34 | install 35 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/wangle: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = wangle 3 | fbsource_path = fbcode/wangle 4 | shipit_project = wangle 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/wangle.git 9 | 10 | [build] 11 | builder = cmake 12 | subdir = wangle 13 | 14 | [cmake.defines.test=on] 15 | BUILD_TESTS=ON 16 | 17 | [cmake.defines.test=off] 18 | BUILD_TESTS=OFF 19 | 20 | [dependencies] 21 | folly 22 | googletest 23 | fizz 24 | 25 | [shipit.pathmap] 26 | fbcode/wangle/public_tld = . 27 | fbcode/wangle = wangle 28 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/watchman: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = watchman 3 | fbsource_path = fbcode/watchman 4 | shipit_project = watchman 5 | shipit_fbcode_builder = true 6 | 7 | [git] 8 | repo_url = https://github.com/facebook/watchman.git 9 | 10 | [build] 11 | builder = cmake 12 | 13 | [dependencies] 14 | boost 15 | cpptoml 16 | fb303 17 | fbthrift 18 | folly 19 | pcre 20 | googletest 21 | 22 | [shipit.pathmap] 23 | fbcode/watchman = . 24 | fbcode/eden/fs = eden/fs 25 | 26 | [shipit.strip] 27 | ^fbcode/eden/fs/(?!.*\.thrift|service/shipit_test_file\.txt) 28 | 29 | [cmake.defines.fb=on] 30 | ENABLE_EDEN_SUPPORT=ON 31 | 32 | # FB macos specific settings 33 | [cmake.defines.all(fb=on,os=darwin)] 34 | # this path is coupled with the FB internal watchman-osx.spec 35 | WATCHMAN_STATE_DIR=/opt/facebook/watchman/var/run/watchman 36 | # tell cmake not to try to create /opt/facebook/... 37 | INSTALL_WATCHMAN_STATE_DIR=OFF 38 | 39 | [depends.environment] 40 | WATCHMAN_VERSION_OVERRIDE 41 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/zlib: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = zlib 3 | 4 | [rpms] 5 | zlib-devel 6 | zlib-static 7 | 8 | [debs] 9 | zlib1g-dev 10 | 11 | [download] 12 | url = http://www.zlib.net/zlib-1.2.11.tar.gz 13 | sha256 = c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 14 | 15 | [build.os=windows] 16 | builder = cmake 17 | subdir = zlib-1.2.11 18 | 19 | # Every platform but windows ships with zlib, so just skip 20 | # building on not(windows) 21 | [build.not(os=windows)] 22 | builder = nop 23 | -------------------------------------------------------------------------------- /build/fbcode_builder/manifests/zstd: -------------------------------------------------------------------------------- 1 | [manifest] 2 | name = zstd 3 | 4 | [rpms] 5 | libzstd-devel 6 | libzstd 7 | 8 | [debs] 9 | libzstd-dev 10 | 11 | [download] 12 | url = https://github.com/facebook/zstd/releases/download/v1.4.5/zstd-1.4.5.tar.gz 13 | sha256 = 98e91c7c6bf162bf90e4e70fdbc41a8188b9fa8de5ad840c401198014406ce9e 14 | 15 | [build] 16 | builder = cmake 17 | subdir = zstd-1.4.5/build/cmake 18 | 19 | # The zstd cmake build explicitly sets the install name 20 | # for the shared library in such a way that cmake discards 21 | # the path to the library from the install_name, rendering 22 | # the library non-resolvable during the build. The short 23 | # term solution for this is just to link static on macos. 24 | [cmake.defines.os=darwin] 25 | ZSTD_BUILD_SHARED = OFF 26 | 27 | [cmake.defines.os=windows] 28 | ZSTD_BUILD_SHARED = OFF 29 | -------------------------------------------------------------------------------- /build/fbcode_builder/parse_args.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 'Argument parsing logic shared by all fbcode_builder CLI tools.' 8 | 9 | import argparse 10 | import logging 11 | 12 | from shell_quoting import raw_shell, ShellQuoted 13 | 14 | 15 | def parse_args_to_fbcode_builder_opts(add_args_fn, top_level_opts, opts, help): 16 | ''' 17 | 18 | Provides some standard arguments: --debug, --option, --shell-quoted-option 19 | 20 | Then, calls `add_args_fn(parser)` to add application-specific arguments. 21 | 22 | `opts` are first used as defaults for the various command-line 23 | arguments. Then, the parsed arguments are mapped back into `opts`, 24 | which then become the values for `FBCodeBuilder.option()`, to be used 25 | both by the builder and by `get_steps_fn()`. 26 | 27 | `help` is printed in response to the `--help` argument. 28 | 29 | ''' 30 | top_level_opts = set(top_level_opts) 31 | 32 | parser = argparse.ArgumentParser( 33 | description=help, 34 | formatter_class=argparse.RawDescriptionHelpFormatter 35 | ) 36 | 37 | add_args_fn(parser) 38 | 39 | parser.add_argument( 40 | '--option', nargs=2, metavar=('KEY', 'VALUE'), action='append', 41 | default=[ 42 | (k, v) for k, v in opts.items() 43 | if k not in top_level_opts and not isinstance(v, ShellQuoted) 44 | ], 45 | help='Set project-specific options. These are assumed to be raw ' 46 | 'strings, to be shell-escaped as needed. Default: %(default)s.', 47 | ) 48 | parser.add_argument( 49 | '--shell-quoted-option', nargs=2, metavar=('KEY', 'VALUE'), 50 | action='append', 51 | default=[ 52 | (k, raw_shell(v)) for k, v in opts.items() 53 | if k not in top_level_opts and isinstance(v, ShellQuoted) 54 | ], 55 | help='Set project-specific options. These are assumed to be shell-' 56 | 'quoted, and may be used in commands as-is. Default: %(default)s.', 57 | ) 58 | 59 | parser.add_argument('--debug', action='store_true', help='Log more') 60 | args = parser.parse_args() 61 | 62 | logging.basicConfig( 63 | level=logging.DEBUG if args.debug else logging.INFO, 64 | format='%(levelname)s: %(message)s' 65 | ) 66 | 67 | # Map command-line args back into opts. 68 | logging.debug('opts before command-line arguments: {0}'.format(opts)) 69 | 70 | new_opts = {} 71 | for key in top_level_opts: 72 | val = getattr(args, key) 73 | # Allow clients to unset a default by passing a value of None in opts 74 | if val is not None: 75 | new_opts[key] = val 76 | for key, val in args.option: 77 | new_opts[key] = val 78 | for key, val in args.shell_quoted_option: 79 | new_opts[key] = ShellQuoted(val) 80 | 81 | logging.debug('opts after command-line arguments: {0}'.format(new_opts)) 82 | 83 | return new_opts 84 | -------------------------------------------------------------------------------- /build/fbcode_builder/shell_builder.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | ''' 9 | shell_builder.py allows running the fbcode_builder logic 10 | on the host rather than in a container. 11 | 12 | It emits a bash script with set -exo pipefail configured such that 13 | any failing step will cause the script to exit with failure. 14 | 15 | == How to run it? == 16 | 17 | cd build 18 | python fbcode_builder/shell_builder.py > ~/run.sh 19 | bash ~/run.sh 20 | ''' 21 | 22 | import os 23 | import distutils.spawn 24 | 25 | from fbcode_builder import FBCodeBuilder 26 | from shell_quoting import ( 27 | raw_shell, shell_comment, shell_join, ShellQuoted 28 | ) 29 | from utils import recursively_flatten_list 30 | 31 | 32 | class ShellFBCodeBuilder(FBCodeBuilder): 33 | def _render_impl(self, steps): 34 | return raw_shell(shell_join('\n', recursively_flatten_list(steps))) 35 | 36 | def set_env(self, key, value): 37 | return ShellQuoted("export {key}={val}").format(key=key, val=value) 38 | 39 | def workdir(self, dir): 40 | return [ 41 | ShellQuoted('mkdir -p {d} && cd {d}').format( 42 | d=dir 43 | ), 44 | ] 45 | 46 | def run(self, shell_cmd): 47 | return ShellQuoted('{cmd}').format(cmd=shell_cmd) 48 | 49 | def step(self, name, actions): 50 | assert '\n' not in name, 'Name {0} would span > 1 line'.format(name) 51 | b = ShellQuoted('') 52 | return [ShellQuoted('### {0} ###'.format(name)), b] + actions + [b] 53 | 54 | def setup(self): 55 | steps = [ 56 | ShellQuoted('set -exo pipefail'), 57 | ] + self.create_python_venv() + self.python_venv() 58 | if self.has_option('ccache_dir'): 59 | ccache_dir = self.option('ccache_dir') 60 | steps += [ 61 | ShellQuoted( 62 | # Set CCACHE_DIR before the `ccache` invocations below. 63 | 'export CCACHE_DIR={ccache_dir} ' 64 | 'CC="ccache ${{CC:-gcc}}" CXX="ccache ${{CXX:-g++}}"' 65 | ).format(ccache_dir=ccache_dir) 66 | ] 67 | return steps 68 | 69 | def comment(self, comment): 70 | return shell_comment(comment) 71 | 72 | def copy_local_repo(self, dir, dest_name): 73 | return [ 74 | ShellQuoted('cp -r {dir} {dest_name}').format( 75 | dir=dir, 76 | dest_name=dest_name 77 | ), 78 | ] 79 | 80 | 81 | def find_project_root(): 82 | here = os.path.dirname(os.path.realpath(__file__)) 83 | maybe_root = os.path.dirname(os.path.dirname(here)) 84 | if os.path.isdir(os.path.join(maybe_root, '.git')): 85 | return maybe_root 86 | raise RuntimeError( 87 | "I expected shell_builder.py to be in the " 88 | "build/fbcode_builder subdir of a git repo") 89 | 90 | 91 | def persistent_temp_dir(repo_root): 92 | escaped = repo_root.replace('/', 'sZs').replace('\\', 'sZs').replace(':', '') 93 | return os.path.join(os.path.expandvars("$HOME"), '.fbcode_builder-' + escaped) 94 | 95 | 96 | if __name__ == '__main__': 97 | from utils import read_fbcode_builder_config, build_fbcode_builder_config 98 | repo_root = find_project_root() 99 | temp = persistent_temp_dir(repo_root) 100 | 101 | config = read_fbcode_builder_config('fbcode_builder_config.py') 102 | builder = ShellFBCodeBuilder(projects_dir=temp) 103 | 104 | if distutils.spawn.find_executable('ccache'): 105 | builder.add_option('ccache_dir', 106 | os.environ.get('CCACHE_DIR', os.path.join(temp, '.ccache'))) 107 | builder.add_option('prefix', os.path.join(temp, 'installed')) 108 | builder.add_option('make_parallelism', 4) 109 | builder.add_option( 110 | '{project}:local_repo_dir'.format(project=config['github_project']), 111 | repo_root) 112 | make_steps = build_fbcode_builder_config(config) 113 | steps = make_steps(builder) 114 | print(builder.render(steps)) 115 | -------------------------------------------------------------------------------- /build/fbcode_builder/shell_quoting.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | ''' 8 | 9 | Almost every FBCodeBuilder string is ultimately passed to a shell. Escaping 10 | too little or too much tends to be the most common error. The utilities in 11 | this file give a systematic way of avoiding such bugs: 12 | - When you write literal strings destined for the shell, use `ShellQuoted`. 13 | - When these literal strings are parameterized, use `ShellQuoted.format`. 14 | - Any parameters that are raw strings get `shell_quote`d automatically, 15 | while any ShellQuoted parameters will be left intact. 16 | - Use `path_join` to join path components. 17 | - Use `shell_join` to join already-quoted command arguments or shell lines. 18 | 19 | ''' 20 | 21 | import os 22 | 23 | from collections import namedtuple 24 | 25 | 26 | class ShellQuoted(namedtuple('ShellQuoted', ('do_not_use_raw_str',))): 27 | ''' 28 | 29 | Wrap a string with this to make it transparent to shell_quote(). It 30 | will almost always suffice to use ShellQuoted.format(), path_join(), 31 | or shell_join(). 32 | 33 | If you really must, use raw_shell() to access the raw string. 34 | 35 | ''' 36 | 37 | def __new__(cls, s): 38 | 'No need to nest ShellQuoted.' 39 | return super(ShellQuoted, cls).__new__( 40 | cls, s.do_not_use_raw_str if isinstance(s, ShellQuoted) else s 41 | ) 42 | 43 | def __str__(self): 44 | raise RuntimeError( 45 | 'One does not simply convert {0} to a string -- use path_join() ' 46 | 'or ShellQuoted.format() instead'.format(repr(self)) 47 | ) 48 | 49 | def __repr__(self): 50 | return '{0}({1})'.format( 51 | self.__class__.__name__, repr(self.do_not_use_raw_str) 52 | ) 53 | 54 | def format(self, **kwargs): 55 | ''' 56 | 57 | Use instead of str.format() when the arguments are either 58 | `ShellQuoted()` or raw strings needing to be `shell_quote()`d. 59 | 60 | Positional args are deliberately not supported since they are more 61 | error-prone. 62 | 63 | ''' 64 | return ShellQuoted(self.do_not_use_raw_str.format(**dict( 65 | (k, shell_quote(v).do_not_use_raw_str) for k, v in kwargs.items() 66 | ))) 67 | 68 | 69 | def shell_quote(s): 70 | 'Quotes a string if it is not already quoted' 71 | return s if isinstance(s, ShellQuoted) \ 72 | else ShellQuoted("'" + str(s).replace("'", "'\\''") + "'") 73 | 74 | 75 | def raw_shell(s): 76 | 'Not a member of ShellQuoted so we get a useful error for raw strings' 77 | if isinstance(s, ShellQuoted): 78 | return s.do_not_use_raw_str 79 | raise RuntimeError('{0} should have been ShellQuoted'.format(s)) 80 | 81 | 82 | def shell_join(delim, it): 83 | 'Joins an iterable of ShellQuoted with a delimiter between each two' 84 | return ShellQuoted(delim.join(raw_shell(s) for s in it)) 85 | 86 | 87 | def path_join(*args): 88 | 'Joins ShellQuoted and raw pieces of paths to make a shell-quoted path' 89 | return ShellQuoted(os.path.join(*[ 90 | raw_shell(shell_quote(s)) for s in args 91 | ])) 92 | 93 | 94 | def shell_comment(c): 95 | 'Do not shell-escape raw strings in comments, but do handle line breaks.' 96 | return ShellQuoted('# {c}').format(c=ShellQuoted( 97 | (raw_shell(c) if isinstance(c, ShellQuoted) else c) 98 | .replace('\n', '\n# ') 99 | )) 100 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookarchive/fbmeshd/13bb3bc12b07632d5e2b4770bae0d0c154d6b2c6/build/fbcode_builder/specs/__init__.py -------------------------------------------------------------------------------- /build/fbcode_builder/specs/fbthrift.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.fizz as fizz 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.sodium as sodium 12 | import specs.wangle as wangle 13 | import specs.zstd as zstd 14 | 15 | 16 | def fbcode_builder_spec(builder): 17 | return { 18 | 'depends_on': [fmt, folly, fizz, sodium, wangle, zstd], 19 | 'steps': [ 20 | builder.fb_github_cmake_install('fbthrift/thrift'), 21 | ], 22 | } 23 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/fbzmq.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.fbthrift as fbthrift 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.gmock as gmock 12 | import specs.sodium as sodium 13 | 14 | from shell_quoting import ShellQuoted 15 | 16 | 17 | def fbcode_builder_spec(builder): 18 | builder.add_option('zeromq/libzmq:git_hash', 'v4.2.2') 19 | return { 20 | 'depends_on': [fmt, folly, fbthrift, gmock, sodium], 21 | 'steps': [ 22 | builder.github_project_workdir('zeromq/libzmq', '.'), 23 | builder.step('Build and install zeromq/libzmq', [ 24 | builder.run(ShellQuoted('./autogen.sh')), 25 | builder.configure(), 26 | builder.make_and_install(), 27 | ]), 28 | 29 | builder.fb_github_project_workdir('fbzmq/_build', 'facebook'), 30 | builder.step('Build and install fbzmq/', [ 31 | builder.cmake_configure('fbzmq/_build'), 32 | # we need the pythonpath to find the thrift compiler 33 | builder.run(ShellQuoted( 34 | 'PYTHONPATH="$PYTHONPATH:"{p}/lib/python2.7/site-packages ' 35 | 'make -j {n}' 36 | ).format(p=builder.option('prefix'), n=builder.option('make_parallelism'))), 37 | builder.run(ShellQuoted('make install')), 38 | ]), 39 | ], 40 | } 41 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/fizz.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.gmock as gmock 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.sodium as sodium 12 | 13 | 14 | def fbcode_builder_spec(builder): 15 | builder.add_option( 16 | "fizz/fizz/build:cmake_defines", 17 | { 18 | # Fizz's build is kind of broken, in the sense that both `mvfst` 19 | # and `proxygen` depend on files that are only installed with 20 | # `BUILD_TESTS` enabled, e.g. `fizz/crypto/test/TestUtil.h`. 21 | "BUILD_TESTS": "ON" 22 | }, 23 | ) 24 | return { 25 | "depends_on": [gmock, fmt, folly, sodium], 26 | "steps": [ 27 | builder.fb_github_cmake_install( 28 | "fizz/fizz/build", github_org="facebookincubator" 29 | ) 30 | ], 31 | } 32 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/fmt.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | 9 | def fbcode_builder_spec(builder): 10 | builder.add_option('fmtlib/fmt:git_hash', '6.2.1') 11 | builder.add_option( 12 | 'fmtlib/fmt:cmake_defines', 13 | { 14 | # Avoids a bizarred failure to run tests in Bistro: 15 | # test_crontab_selector: error while loading shared libraries: 16 | # libfmt.so.6: cannot open shared object file: 17 | # No such file or directory 18 | 'BUILD_SHARED_LIBS': 'OFF', 19 | } 20 | ) 21 | return { 22 | 'steps': [ 23 | builder.github_project_workdir('fmtlib/fmt', 'build'), 24 | builder.cmake_install('fmtlib/fmt'), 25 | ], 26 | } 27 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/folly.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.fmt as fmt 9 | 10 | 11 | def fbcode_builder_spec(builder): 12 | return { 13 | "depends_on": [fmt], 14 | 'steps': [ 15 | # on macOS the filesystem is typically case insensitive. 16 | # We need to ensure that the CWD is not the folly source 17 | # dir when we build, otherwise the system will decide 18 | # that `folly/String.h` is the file it wants when including 19 | # `string.h` and the build will fail. 20 | builder.fb_github_project_workdir('folly/_build'), 21 | builder.cmake_install('facebook/folly'), 22 | ], 23 | } 24 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/gmock.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | 9 | def fbcode_builder_spec(builder): 10 | builder.add_option('google/googletest:git_hash', 'release-1.8.1') 11 | builder.add_option( 12 | 'google/googletest:cmake_defines', 13 | { 14 | 'BUILD_GTEST': 'ON', 15 | # Avoid problems with MACOSX_RPATH 16 | 'BUILD_SHARED_LIBS': 'OFF', 17 | } 18 | ) 19 | return { 20 | 'steps': [ 21 | builder.github_project_workdir('google/googletest', 'build'), 22 | builder.cmake_install('google/googletest'), 23 | ], 24 | } 25 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/mvfst.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.gmock as gmock 9 | import specs.folly as folly 10 | import specs.fizz as fizz 11 | 12 | 13 | def fbcode_builder_spec(builder): 14 | # Projects that **depend** on mvfst should don't need to build tests. 15 | builder.add_option( 16 | "mvfst/build:cmake_defines", 17 | { 18 | # This is set to ON in the mvfst `fbcode_builder_config.py` 19 | "BUILD_TESTS": "OFF" 20 | }, 21 | ) 22 | return { 23 | "depends_on": [gmock, folly, fizz], 24 | "steps": [ 25 | builder.fb_github_cmake_install( 26 | "mvfst/build", github_org="facebookincubator" 27 | ) 28 | ], 29 | } 30 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/proxygen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.gmock as gmock 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.fizz as fizz 12 | import specs.mvfst as mvfst 13 | import specs.sodium as sodium 14 | import specs.wangle as wangle 15 | import specs.zstd as zstd 16 | 17 | 18 | def fbcode_builder_spec(builder): 19 | # Projects that **depend** on proxygen should don't need to build tests 20 | # or QUIC support. 21 | builder.add_option( 22 | "proxygen/proxygen:cmake_defines", 23 | { 24 | # These 2 are set to ON in `proxygen_quic.py` 25 | "BUILD_QUIC": "OFF", 26 | "BUILD_TESTS": "OFF", 27 | # For bistro 28 | "BUILD_SHARED_LIBS": "OFF", 29 | }, 30 | ) 31 | 32 | return { 33 | "depends_on": [gmock, fmt, folly, wangle, fizz, sodium, zstd, mvfst], 34 | "steps": [builder.fb_github_cmake_install("proxygen/proxygen", "..")], 35 | } 36 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/proxygen_quic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.gmock as gmock 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.fizz as fizz 12 | import specs.mvfst as mvfst 13 | import specs.sodium as sodium 14 | import specs.wangle as wangle 15 | import specs.zstd as zstd 16 | 17 | # DO NOT USE THIS AS A LIBRARY -- this is currently effectively just part 18 | # ofthe implementation of proxygen's `fbcode_builder_config.py`. This is 19 | # why this builds tests and sets `BUILD_QUIC`. 20 | def fbcode_builder_spec(builder): 21 | builder.add_option( 22 | "proxygen/proxygen:cmake_defines", 23 | {"BUILD_QUIC": "ON", "BUILD_SHARED_LIBS": "OFF", "BUILD_TESTS": "ON"}, 24 | ) 25 | return { 26 | "depends_on": [gmock, fmt, folly, wangle, fizz, sodium, zstd, mvfst], 27 | "steps": [builder.fb_github_cmake_install("proxygen/proxygen", "..")], 28 | } 29 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/re2.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | 9 | def fbcode_builder_spec(builder): 10 | return { 11 | 'steps': [ 12 | builder.github_project_workdir('google/re2', 'build'), 13 | builder.cmake_install('google/re2'), 14 | ], 15 | } 16 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/rocksdb.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | 9 | def fbcode_builder_spec(builder): 10 | builder.add_option("rocksdb/_build:cmake_defines", { 11 | "USE_RTTI": "1", 12 | "PORTABLE": "ON", 13 | }) 14 | return { 15 | "steps": [ 16 | builder.fb_github_cmake_install("rocksdb/_build"), 17 | ], 18 | } 19 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/sodium.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | from shell_quoting import ShellQuoted 9 | 10 | 11 | def fbcode_builder_spec(builder): 12 | builder.add_option('jedisct1/libsodium:git_hash', 'stable') 13 | return { 14 | 'steps': [ 15 | builder.github_project_workdir('jedisct1/libsodium', '.'), 16 | builder.step('Build and install jedisct1/libsodium', [ 17 | builder.run(ShellQuoted('./autogen.sh')), 18 | builder.configure(), 19 | builder.make_and_install(), 20 | ]), 21 | ], 22 | } 23 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/wangle.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | import specs.gmock as gmock 9 | import specs.fmt as fmt 10 | import specs.folly as folly 11 | import specs.fizz as fizz 12 | import specs.sodium as sodium 13 | 14 | 15 | def fbcode_builder_spec(builder): 16 | # Projects that **depend** on wangle need not spend time on tests. 17 | builder.add_option( 18 | "wangle/wangle/build:cmake_defines", 19 | { 20 | # This is set to ON in the wangle `fbcode_builder_config.py` 21 | "BUILD_TESTS": "OFF" 22 | }, 23 | ) 24 | return { 25 | "depends_on": [gmock, fmt, folly, fizz, sodium], 26 | "steps": [builder.fb_github_cmake_install("wangle/wangle/build")], 27 | } 28 | -------------------------------------------------------------------------------- /build/fbcode_builder/specs/zstd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 8 | from shell_quoting import ShellQuoted 9 | 10 | 11 | def fbcode_builder_spec(builder): 12 | # This API should change rarely, so build the latest tag instead of master. 13 | builder.add_option( 14 | 'facebook/zstd:git_hash', 15 | ShellQuoted('$(git describe --abbrev=0 --tags origin/master)') 16 | ) 17 | return { 18 | 'steps': [ 19 | builder.github_project_workdir('facebook/zstd', '.'), 20 | builder.step('Build and install zstd', [ 21 | builder.make_and_install(make_vars={ 22 | 'PREFIX': builder.option('prefix'), 23 | }) 24 | ]), 25 | ], 26 | } 27 | -------------------------------------------------------------------------------- /build/fbcode_builder/travis_docker_build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -uex 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # .travis.yml in the top-level dir explains why this is a separate script. 4 | # Read the docs: ./make_docker_context.py --help 5 | 6 | os_image=${os_image?Must be set by Travis} 7 | gcc_version=${gcc_version?Must be set by Travis} 8 | make_parallelism=${make_parallelism:-4} 9 | # ccache is off unless requested 10 | travis_cache_dir=${travis_cache_dir:-} 11 | # The docker build never times out, unless specified 12 | docker_build_timeout=${docker_build_timeout:-} 13 | 14 | cur_dir="$(readlink -f "$(dirname "$0")")" 15 | 16 | if [[ "$travis_cache_dir" == "" ]]; then 17 | echo "ccache disabled, enable by setting env. var. travis_cache_dir" 18 | ccache_tgz="" 19 | elif [[ -e "$travis_cache_dir/ccache.tgz" ]]; then 20 | ccache_tgz="$travis_cache_dir/ccache.tgz" 21 | else 22 | echo "$travis_cache_dir/ccache.tgz does not exist, starting with empty cache" 23 | ccache_tgz=$(mktemp) 24 | tar -T /dev/null -czf "$ccache_tgz" 25 | fi 26 | 27 | docker_context_dir=$( 28 | cd "$cur_dir/.." # Let the script find our fbcode_builder_config.py 29 | "$cur_dir/make_docker_context.py" \ 30 | --os-image "$os_image" \ 31 | --gcc-version "$gcc_version" \ 32 | --make-parallelism "$make_parallelism" \ 33 | --local-repo-dir "$cur_dir/../.." \ 34 | --ccache-tgz "$ccache_tgz" 35 | ) 36 | cd "${docker_context_dir?Failed to make Docker context directory}" 37 | 38 | # Make it safe to iterate on the .sh in the tree while the script runs. 39 | cp "$cur_dir/docker_build_with_ccache.sh" . 40 | exec ./docker_build_with_ccache.sh \ 41 | --build-timeout "$docker_build_timeout" \ 42 | "$travis_cache_dir" 43 | -------------------------------------------------------------------------------- /build/fbcode_builder/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | from __future__ import absolute_import 4 | from __future__ import division 5 | from __future__ import print_function 6 | from __future__ import unicode_literals 7 | 'Miscellaneous utility functions.' 8 | 9 | import itertools 10 | import logging 11 | import os 12 | import shutil 13 | import subprocess 14 | import sys 15 | 16 | from contextlib import contextmanager 17 | 18 | 19 | def recursively_flatten_list(l): 20 | return itertools.chain.from_iterable( 21 | (recursively_flatten_list(i) if type(i) is list else (i,)) 22 | for i in l 23 | ) 24 | 25 | 26 | def run_command(*cmd, **kwargs): 27 | 'The stdout of most fbcode_builder utilities is meant to be parsed.' 28 | logging.debug('Running: {0} with {1}'.format(cmd, kwargs)) 29 | kwargs['stdout'] = sys.stderr 30 | subprocess.check_call(cmd, **kwargs) 31 | 32 | 33 | @contextmanager 34 | def make_temp_dir(d): 35 | os.mkdir(d) 36 | try: 37 | yield d 38 | finally: 39 | shutil.rmtree(d, ignore_errors=True) 40 | 41 | 42 | def _inner_read_config(path): 43 | ''' 44 | Helper to read a named config file. 45 | The grossness with the global is a workaround for this python bug: 46 | https://bugs.python.org/issue21591 47 | The bug prevents us from defining either a local function or a lambda 48 | in the scope of read_fbcode_builder_config below. 49 | ''' 50 | global _project_dir 51 | full_path = os.path.join(_project_dir, path) 52 | return read_fbcode_builder_config(full_path) 53 | 54 | 55 | def read_fbcode_builder_config(filename): 56 | # Allow one spec to read another 57 | # When doing so, treat paths as relative to the config's project directory. 58 | # _project_dir is a "local" for _inner_read_config; see the comments 59 | # in that function for an explanation of the use of global. 60 | global _project_dir 61 | _project_dir = os.path.dirname(filename) 62 | 63 | scope = {'read_fbcode_builder_config': _inner_read_config} 64 | with open(filename) as config_file: 65 | code = compile(config_file.read(), filename, mode='exec') 66 | exec(code, scope) 67 | return scope['config'] 68 | 69 | 70 | def steps_for_spec(builder, spec, processed_modules=None): 71 | ''' 72 | Sets `builder` configuration, and returns all the builder steps 73 | necessary to build `spec` and its dependencies. 74 | 75 | Traverses the dependencies in depth-first order, honoring the sequencing 76 | in each 'depends_on' list. 77 | ''' 78 | if processed_modules is None: 79 | processed_modules = set() 80 | steps = [] 81 | for module in spec.get('depends_on', []): 82 | if module not in processed_modules: 83 | processed_modules.add(module) 84 | steps.extend(steps_for_spec( 85 | builder, 86 | module.fbcode_builder_spec(builder), 87 | processed_modules 88 | )) 89 | steps.extend(spec.get('steps', [])) 90 | return steps 91 | 92 | 93 | def build_fbcode_builder_config(config): 94 | return lambda builder: builder.build( 95 | steps_for_spec(builder, config['fbcode_builder_spec'](builder)) 96 | ) 97 | -------------------------------------------------------------------------------- /build/run_fbmeshd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # 4 | # Copyright (c) Facebook, Inc. and its affiliates. 5 | # 6 | # This source code is licensed under the MIT license found in the 7 | # LICENSE file in the root directory of this source tree. 8 | # 9 | 10 | # 11 | # NOTE 12 | # 13 | # This script uses the default fbmeshd configuration specified for command line 14 | # flags in the fbmeshd source code. 15 | # 16 | # Override the ones you need to in `/etc/sysconfig/fbmeshd` for custom 17 | # configuration on the node, using this format: 18 | # CONFIG_fbmeshd_='' 19 | # e.g. CONFIG_fbmeshd_node_name='my_new_node_name' 20 | # 21 | # You can also pass an alternate config file path to use, and additional flags 22 | # after the config file path (if present), which will take priority over all 23 | # others. 24 | # e.g. run_fbmeshd.sh /etc/fbmeshd.conf 25 | # e.g. run_fbmeshd.sh --node_name=my_new_node_name 26 | # e.g. run_fbmeshd.sh /etc/fbmeshd.conf --node_name=my_new_node_name 27 | # 28 | 29 | # fbmeshd binary path or command name present on bin paths 30 | FBMESHD=/usr/sbin/fbmeshd 31 | 32 | # 33 | # Load custom configuration if any 34 | # 35 | FBMESHD_CONFIG="/etc/sysconfig/fbmeshd" 36 | FBMESHD_ARGS="$*" 37 | if [ -n "$1" ]; then 38 | if [ "$1" = "--help" ]; then 39 | echo "USAGE: run_fbmeshd.sh [config_file_path] [fbmeshd_flags]" 40 | echo "If config_file_path is not provided, we will source the one at /etc/sysconfig/fbmeshd" 41 | echo "If fbmeshd_flags are provided, they will be passed along to fbmeshd and override any passed by this script" 42 | exit 1 43 | fi 44 | if [ -f "$1" ]; then 45 | FBMESHD_CONFIG=$1 46 | FBMESHD_ARGS="${*:2}" 47 | fi 48 | fi 49 | 50 | if [ -f "${FBMESHD_CONFIG}" ]; then 51 | # shellcheck disable=SC1090 52 | source "${FBMESHD_CONFIG}" 53 | echo "Using fbmeshd config parameters from ${FBMESHD_CONFIG}" 54 | 55 | if [ -d "${FBMESHD_CONFIG}.d" ]; then 56 | for f in "${FBMESHD_CONFIG}.d"/*; do 57 | echo "Overriding fbmeshd config parameters from ${f}" 58 | # shellcheck disable=SC1090 59 | source "${f}"; 60 | done 61 | fi 62 | else 63 | echo "Configuration not found at ${FBMESHD_CONFIG}. Using default!" 64 | fi 65 | 66 | # 67 | # Parse the options into the format that we need for passing to the executable 68 | # 69 | mapfile -t FBMESHD_CONFIG_VARS < <(set -o posix; set | grep '^CONFIG_fbmeshd_' | cut -d '=' -f1) 70 | 71 | FBMESHD_CONFIG_ARGS=() 72 | for var in "${FBMESHD_CONFIG_VARS[@]}" 73 | do 74 | FLAG="${var//CONFIG_fbmeshd_/--}" 75 | VALUE=$(eval "echo $""$var") 76 | FBMESHD_CONFIG_ARGS+=("$FLAG=$VALUE") 77 | done 78 | 79 | # 80 | # Let the magic begin. Keep the options sorted except for log level \m/ 81 | # 82 | 83 | exec ${FBMESHD} \ 84 | --logbufsecs=0 \ 85 | --logtostderr=1 \ 86 | --max_log_size=1 \ 87 | "${FBMESHD_CONFIG_ARGS[@]}" \ 88 | "${FBMESHD_ARGS[@]}" 89 | -------------------------------------------------------------------------------- /fbmeshd/802.11s/AuthsaeCallbackHelpers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | extern "C" { 11 | #include 12 | #include 13 | #include 14 | } 15 | 16 | #include 17 | 18 | // Creates the function callback tables for AMPE and SAE 19 | ampe_cb* getAmpeCallbacks(); 20 | sae_cb* getSaeCallbacks(); 21 | 22 | namespace fbmeshd { 23 | 24 | // This is a static class that provides certain helpers necessary for 25 | // interfacing with libsae 26 | class AuthsaeCallbackHelpers final { 27 | // This class is static, remove default copy/move 28 | AuthsaeCallbackHelpers() = delete; 29 | AuthsaeCallbackHelpers(const AuthsaeCallbackHelpers&) = delete; 30 | AuthsaeCallbackHelpers(AuthsaeCallbackHelpers&&) = delete; 31 | AuthsaeCallbackHelpers& operator=(const AuthsaeCallbackHelpers&) = delete; 32 | AuthsaeCallbackHelpers& operator=(AuthsaeCallbackHelpers&&) = delete; 33 | 34 | public: 35 | // Initialise the static event loop pointer 36 | static void init(fbzmq::ZmqEventLoop& zmqLoop); 37 | 38 | // Methods for controlling timeouts 39 | // 40 | // NOTE: The public-facing timeout ID returned/accepted by these methods is 41 | // abstracted from the timeout IDs used internally by the event loop! 42 | static int64_t addTimeoutToEventLoop( 43 | std::chrono::milliseconds timeout, fbzmq::TimeoutCallback callback); 44 | static void removeTimeoutFromEventLoop(int64_t timeoutId); 45 | 46 | private: 47 | static void verifyInitialized(); 48 | 49 | static fbzmq::ZmqEventLoop* zmqLoop_; 50 | }; 51 | 52 | } // namespace fbmeshd 53 | -------------------------------------------------------------------------------- /fbmeshd/802.11s/AuthsaeConfigHelpers.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | // These are helper functions for Nl80211Handler::initMesh() which are used to 16 | // properly create the SAE (sae_config) and AMPE (mesh_node) configuration 17 | // structs to be passed to authsae. 18 | 19 | FOLLY_NODISCARD authsae_sae_config 20 | createSaeConfig(const fbmeshd::NetInterface& netif); 21 | FOLLY_NODISCARD authsae_mesh_node* createMeshConfig( 22 | fbmeshd::NetInterface& netif); 23 | 24 | // These are helper functions for the helper functions; they are meant for 25 | // internal use only. They are declared in this header in order to enable unit 26 | // testing, which would be impossible with an anonymous namespace. 27 | namespace fbmeshd { 28 | namespace internal { 29 | 30 | void setSupportedBasicRates( 31 | int phyIndex, authsae_meshd_config* mconf, u16* rates, size_t rates_len); 32 | 33 | } // namespace internal 34 | } // namespace fbmeshd 35 | -------------------------------------------------------------------------------- /fbmeshd/802.11s/AuthsaeTypes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | extern "C" { 11 | #include 12 | #include 13 | } 14 | 15 | // This file is intended for typedefs of authsae types whose naming is confusing 16 | // in the context of fbmeshd. 17 | 18 | using authsae_sae_config = sae_config; 19 | using authsae_mesh_node = mesh_node; 20 | using authsae_meshd_config = meshd_config; 21 | -------------------------------------------------------------------------------- /fbmeshd/802.11s/NetInterface.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | extern "C" { 11 | #include 12 | } 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | namespace fbmeshd { 27 | 28 | class NetInterface final { 29 | // This class should never be copied; remove default copy/move 30 | NetInterface() = delete; 31 | NetInterface(const NetInterface&) = delete; 32 | NetInterface& operator=(const NetInterface&) = delete; 33 | 34 | public: 35 | explicit NetInterface(int phyIndex); 36 | 37 | NetInterface(NetInterface&&); 38 | 39 | status_t bringLinkUp(); 40 | status_t bringLinkDown(); 41 | FOLLY_NODISCARD bool isValid() const; 42 | FOLLY_NODISCARD int phyIndex() const; 43 | void addSupportedFrequency(uint32_t freq); 44 | FOLLY_NODISCARD bool isFrequencySupported(uint32_t freq) const; 45 | 46 | // Functions related to authsae-powered secure meshes 47 | ieee80211_supported_band* getSupportedBand(ieee80211_band band); 48 | FOLLY_NODISCARD authsae_mesh_node* getMeshConfig(); 49 | FOLLY_NODISCARD const authsae_mesh_node* getMeshConfig() const; 50 | 51 | folly::Optional maybeIfName; 52 | folly::Optional maybeIfIndex; 53 | std::string phyName; 54 | std::string meshId; 55 | int frequency{0}; 56 | int centerFreq1{0}; 57 | int centerFreq2{0}; 58 | int channelWidth{NL80211_CHAN_WIDTH_20}; 59 | bool isMeshCapable{false}; 60 | folly::Optional maybeMacAddress; 61 | 62 | // Encryption options 63 | bool isEncrypted{false}; 64 | std::string encryptionPassword; 65 | std::vector encryptionSaeGroups; 66 | int encryptionDebug; 67 | 68 | // 802.11s specific options 69 | uint16_t maxPeerLinks; 70 | folly::Optional maybeRssiThreshold; 71 | uint8_t ttl; 72 | uint8_t elementTtl; 73 | uint32_t hwmpActivePathTimeout; 74 | uint32_t hwmpRannInterval; 75 | 76 | friend std::ostream& operator<<( 77 | std::ostream& os, const NetInterface& netIntf); 78 | 79 | private: 80 | status_t setLinkFlags(int flags); 81 | 82 | int phyIndex_{0}; 83 | std::set frequencies_; 84 | 85 | // Configs for authsae-powered secure meshes 86 | authsae_mesh_node meshConfig_{}; 87 | authsae_meshd_config meshdConfig_{}; 88 | }; 89 | 90 | std::ostream& operator<<(std::ostream& os, const NetInterface& netIntf); 91 | 92 | } // namespace fbmeshd 93 | -------------------------------------------------------------------------------- /fbmeshd/FollySignalHandler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace fbmeshd { 16 | 17 | /** 18 | * A signal handler for auxiliary event loops using folly::EventBase which stops 19 | * the underlying zmq event loop upon signal catching for graceful exit. 20 | */ 21 | class FollySignalHandler final : public folly::AsyncSignalHandler { 22 | // This class should never be copied; remove default copy/move 23 | FollySignalHandler() = delete; 24 | FollySignalHandler(const FollySignalHandler&) = delete; 25 | FollySignalHandler(FollySignalHandler&&) = delete; 26 | FollySignalHandler& operator=(const FollySignalHandler&) = delete; 27 | FollySignalHandler& operator=(FollySignalHandler&&) = delete; 28 | 29 | public: 30 | explicit FollySignalHandler(folly::EventBase& evb, fbzmq::ZmqEventLoop& evl) 31 | : folly::AsyncSignalHandler(&evb), evl_{evl} {} 32 | 33 | void 34 | signalReceived(int sig) noexcept override { 35 | LOG(INFO) << "EventBase received signal: " << sig; 36 | switch (sig) { 37 | case SIGABRT: 38 | case SIGINT: 39 | case SIGKILL: 40 | case SIGTERM: { 41 | LOG(INFO) << "Stopping ZmqEventLoop..."; 42 | evl_.runImmediatelyOrInEventLoop([&]() { evl_.stop(); }); 43 | break; 44 | } 45 | } 46 | } 47 | 48 | private: 49 | fbzmq::ZmqEventLoop& evl_; 50 | }; 51 | 52 | } // namespace fbmeshd 53 | -------------------------------------------------------------------------------- /fbmeshd/SignalHandler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | /** 17 | * A commom signal handler which stops the underlying zmq event loop upon signal 18 | * catching for graceful exit. Use AsyncSignalHandler directly if you intend to 19 | * do more. 20 | */ 21 | class SignalHandler final : public fbzmq::AsyncSignalHandler { 22 | // This class should never be copied; remove default copy/move 23 | SignalHandler() = delete; 24 | SignalHandler(const SignalHandler&) = delete; 25 | SignalHandler(SignalHandler&&) = delete; 26 | SignalHandler& operator=(const SignalHandler&) = delete; 27 | SignalHandler& operator=(SignalHandler&&) = delete; 28 | 29 | public: 30 | explicit SignalHandler(fbzmq::ZmqEventLoop& evl) 31 | : fbzmq::AsyncSignalHandler(&evl) {} 32 | 33 | void 34 | signalReceived(int sig) noexcept override { 35 | LOG(INFO) << "ZmqEventLoop received signal: " << sig; 36 | switch (sig) { 37 | case SIGABRT: 38 | case SIGINT: 39 | case SIGKILL: 40 | case SIGTERM: { 41 | LOG(INFO) << "Stopping ZmqEventLoop..."; 42 | auto evl = getZmqEventLoop(); 43 | evl->stop(); 44 | break; 45 | } 46 | } 47 | } 48 | }; 49 | 50 | } // namespace fbmeshd 51 | -------------------------------------------------------------------------------- /fbmeshd/common/Constants.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "Constants.h" 9 | 10 | using namespace fbmeshd; 11 | 12 | // Cipher suite selectors (see 802.11-2016 section 9.4.2.25.2 Cipher suites 13 | // and Table 9-131 Cipher suite selectors) 14 | constexpr unsigned int Constants::CIPHER_CCMP; 15 | constexpr unsigned int Constants::CIPHER_AES_CMAC; 16 | 17 | constexpr int32_t Constants::kMinRssiThreshold; 18 | 19 | constexpr std::chrono::seconds Constants::kMaxPeerInactiveTime; 20 | 21 | constexpr std::chrono::seconds Constants::kDefaultHalfLife; 22 | constexpr std::chrono::seconds Constants::kDefaultMaxSuppressLimit; 23 | 24 | constexpr std::array Constants::kFacebookOui; 25 | -------------------------------------------------------------------------------- /fbmeshd/common/Constants.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | class Constants final { 17 | // This class is static, remove default copy/move 18 | Constants() = delete; 19 | Constants(const Constants&) = delete; 20 | Constants(Constants&&) = delete; 21 | Constants& operator=(const Constants&) = delete; 22 | Constants& operator=(Constants&&) = delete; 23 | 24 | public: 25 | // Cipher suite selectors (see 802.11-2016 section 9.4.2.25.2 Cipher suites 26 | // and Table 9-131 Cipher suite selectors) 27 | static constexpr unsigned int CIPHER_CCMP{0x000FAC04}; 28 | static constexpr unsigned int CIPHER_AES_CMAC{0x000FAC06}; 29 | 30 | // Lowest RSSI threshold we will try meshing with 31 | static constexpr int kMinRssiThreshold{-100}; 32 | 33 | // Maximum time a peer can be inactive before being removed from list of 34 | // neighbors 35 | static constexpr std::chrono::seconds kMaxPeerInactiveTime{120}; 36 | 37 | // Gateway Connectivity Manager Robustness default 38 | static constexpr unsigned int kDefaultRobustness{2}; 39 | 40 | // Gateway Connectivity Manager Route Dampener defaults 41 | static constexpr unsigned int kDefaultPenalty{1000}; 42 | static constexpr unsigned int kDefaultSuppressLimit{2000}; 43 | static constexpr unsigned int kDefaultReuseLimit{750}; 44 | static constexpr std::chrono::seconds kDefaultHalfLife{1 * 60}; 45 | static constexpr std::chrono::seconds kDefaultMaxSuppressLimit{3 * 60}; 46 | 47 | // Facebook OUI 48 | static constexpr std::array kFacebookOui{0xa4, 0x0e, 0x2b}; 49 | }; 50 | 51 | } // namespace fbmeshd 52 | -------------------------------------------------------------------------------- /fbmeshd/common/ErrorCodes.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #define R_SUCCESS 0 11 | #define ERR_RTNETLINK_ALLOCATE_SOCKET 1 // Failed to allocate rtnetlink socket 12 | #define ERR_IFINDEX_NOT_FOUND 2 // Failed to find ifIndex 13 | #define ERR_RTNL_ALLOCATE_OBJ 3 // Failed to allocate rtnl link object 14 | #define ERR_CHANGE_LINKSTATE 4 // Failed to change link state in kernel 15 | #define ERR_IFNAME 5 16 | #define ERR_NETLINK_OTHER 17 // Other Netlink errors 17 | #define ERR_UNSUPPORTED_CONFIG 18 // Provided mesh config is not supported 18 | #define ERR_INVALID_ARGUMENT_VALUE 19 // Provided argument value is invalid 19 | #define ERR_AUTHSAE 20 // Failure coming from authsae during authentication 20 | 21 | typedef int status_t; 22 | -------------------------------------------------------------------------------- /fbmeshd/common/Util.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace fbmeshd { 22 | 23 | // Convert a GFlags CSV string to a std::vector by applying a processing 24 | // function for individual elements of the list 25 | template 26 | std::vector 27 | parseCsvFlag( 28 | const std::string& csvString, 29 | const std::function& processFunc) { 30 | VLOG(8) << folly::sformat("::{}()", __func__); 31 | 32 | if (csvString.empty()) { 33 | return {}; 34 | } 35 | 36 | std::vector result; 37 | std::stringstream ss{csvString}; 38 | 39 | while (ss.good()) { 40 | std::string substr; 41 | getline(ss, substr, ','); 42 | result.push_back(processFunc(substr)); 43 | } 44 | 45 | return result; 46 | } 47 | 48 | } // namespace fbmeshd 49 | -------------------------------------------------------------------------------- /fbmeshd/debugfs/DebugFsWriter.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "fbmeshd/debugfs/DebugFsWriter.h" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | DEFINE_bool( 16 | enable_debugfs, 17 | true, 18 | "Write debug stats into the directory at --debugfs_dir"); 19 | DEFINE_string( 20 | debugfs_dir, 21 | "/tmp/fbmeshd_debugfs", 22 | "Directory to write debug stats files into. It will be created if its " 23 | "parent exists but it does not."); 24 | 25 | namespace fbmeshd { 26 | 27 | void DebugFsWriter::writeDebugStat(const std::string& key, bool value) { 28 | VLOG(8) << folly::sformat("DebugFsWriter::{}(value: {})", __func__, value); 29 | if (FLAGS_enable_debugfs) { 30 | writeDebugStat(key, std::string{value ? "true" : "false"}); 31 | } 32 | } 33 | 34 | void DebugFsWriter::writeDebugStat(const std::string& key, double value) { 35 | VLOG(8) << folly::sformat("DebugFsWriter::{}(value: {})", __func__, value); 36 | if (FLAGS_enable_debugfs) { 37 | writeDebugStat(key, folly::sformat("{}", value)); 38 | } 39 | } 40 | 41 | void DebugFsWriter::writeDebugStat( 42 | const std::string& key, 43 | const std::string& value) { 44 | VLOG(8) << folly::sformat("DebugFsWriter::{}(value: {})", __func__, value); 45 | if (FLAGS_enable_debugfs) { 46 | // Make debugfs dir if it doesn't exist (works only if its parent exists) 47 | mkdir(FLAGS_debugfs_dir.c_str(), 0644); 48 | 49 | // Write the stat to the debug dir 50 | std::ofstream file; 51 | file.open(folly::sformat("{}/{}", FLAGS_debugfs_dir, key), std::ios::trunc); 52 | file << key << " " << value << std::endl; 53 | file.close(); 54 | } 55 | } 56 | 57 | } // namespace fbmeshd 58 | -------------------------------------------------------------------------------- /fbmeshd/debugfs/DebugFsWriter.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | 14 | DECLARE_bool(enable_debugfs); 15 | DECLARE_string(debugfs_dir); 16 | 17 | namespace fbmeshd { 18 | 19 | // This class is intended as a utility class for writing stats to a directory in 20 | // the style of debugfs 21 | class DebugFsWriter final { 22 | public: 23 | DebugFsWriter(); 24 | ~DebugFsWriter() = default; 25 | DebugFsWriter(const DebugFsWriter&) = delete; 26 | DebugFsWriter& operator=(const DebugFsWriter&) = delete; 27 | DebugFsWriter(DebugFsWriter&&) = delete; 28 | DebugFsWriter& operator=(DebugFsWriter&&) = delete; 29 | 30 | static void writeDebugStat(const std::string& key, bool value); 31 | static void writeDebugStat(const std::string& key, double value); 32 | static void writeDebugStat(const std::string& key, const std::string& value); 33 | }; 34 | 35 | } // namespace fbmeshd 36 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/GatewayConnectivityMonitor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace fbmeshd { 20 | 21 | class GatewayConnectivityMonitor : public RouteDampener { 22 | public: 23 | explicit GatewayConnectivityMonitor( 24 | folly::EventBase* evb, 25 | Nl80211Handler& nlHandler, 26 | const std::string& monitoredInterface, 27 | std::vector monitoredAddresses, 28 | std::chrono::seconds monitorInterval, 29 | std::chrono::seconds monitorSocketTimeout, 30 | unsigned int penalty, 31 | unsigned int suppressLimit, 32 | unsigned int reuseLimit, 33 | std::chrono::seconds halfLife, 34 | std::chrono::seconds maxSuppressLimit, 35 | unsigned int robustness, 36 | uint8_t setRootModeIfGate, 37 | Routing* routing, 38 | StatsClient& statsClient); 39 | 40 | GatewayConnectivityMonitor() = delete; 41 | ~GatewayConnectivityMonitor() override = default; 42 | GatewayConnectivityMonitor(const GatewayConnectivityMonitor&) = delete; 43 | GatewayConnectivityMonitor(GatewayConnectivityMonitor&&) = delete; 44 | GatewayConnectivityMonitor& operator=(const GatewayConnectivityMonitor&) = 45 | delete; 46 | GatewayConnectivityMonitor& operator=(GatewayConnectivityMonitor&&) = delete; 47 | 48 | private: 49 | void setStat(const std::string& path, int value) override; 50 | void dampen() override; 51 | void undampen() override; 52 | 53 | bool probeWanConnectivity(); 54 | bool probeWanConnectivityRobustly(); 55 | 56 | void checkRoutesAndAdvertise(); 57 | 58 | void advertiseDefaultRoute(); 59 | void withdrawDefaultRoute(); 60 | 61 | private: 62 | Nl80211Handler& nlHandler_; 63 | 64 | const std::string monitoredInterface_; 65 | const std::vector monitoredAddresses_; 66 | const std::chrono::seconds monitorSocketTimeout_; 67 | const unsigned int robustness_; 68 | const uint8_t setRootModeIfGate_; 69 | Routing* routing_{nullptr}; 70 | 71 | std::unique_ptr connectivityCheckTimer_; 72 | 73 | StatsClient& statsClient_; 74 | 75 | bool isGatewayActive_{false}; 76 | }; 77 | 78 | } // namespace fbmeshd 79 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/RouteDampener.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | namespace fbmeshd { 22 | 23 | // This is a loose implementation of route dampening similar to BGP. Generally 24 | // is not advisable to deploy bgp route dampening but that mostly has to do with 25 | // the network effects of route propagation. This should be better as its only 26 | // done on the edge. 27 | class RouteDampener { 28 | public: 29 | explicit RouteDampener( 30 | folly::EventBase* evb, 31 | unsigned int penalty = Constants::kDefaultPenalty, 32 | unsigned int suppressLimit = Constants::kDefaultSuppressLimit, 33 | unsigned int reuseLimit = Constants::kDefaultReuseLimit, 34 | std::chrono::seconds halfLife = Constants::kDefaultHalfLife, 35 | std::chrono::seconds maxSuppressLimit = 36 | Constants::kDefaultMaxSuppressLimit); 37 | RouteDampener() = delete; 38 | virtual ~RouteDampener() = default; 39 | RouteDampener(const RouteDampener&) = delete; 40 | RouteDampener& operator=(const RouteDampener&) = delete; 41 | RouteDampener(RouteDampener&&) = delete; 42 | RouteDampener& operator=(RouteDampener&&) = delete; 43 | 44 | public: 45 | void flap(); 46 | 47 | bool isDampened() const; 48 | 49 | bool isValid() const; 50 | 51 | virtual void dampen() = 0; 52 | virtual void undampen() = 0; 53 | virtual void setStat(const std::string& path, int value) = 0; 54 | 55 | virtual void 56 | userHalfLifeTimerExpired() {} 57 | virtual void 58 | userSuppressLimitTimerExpired() {} 59 | 60 | void setHistory(unsigned int newHistory); 61 | 62 | unsigned int getHistory() const; 63 | 64 | template 65 | void 66 | setRdStat(const std::string& templateS, int value, Params&&... params) { 67 | static constexpr folly::StringPiece rdPrefixTemplate{"route_dampener.{}"}; 68 | setStat( 69 | folly::sformat( 70 | rdPrefixTemplate, 71 | folly::sformat(templateS, std::forward(params)...)), 72 | value); 73 | } 74 | 75 | private: 76 | void halfLifeTimerExpired(); 77 | void maxSuppressLimitTimerExpired(); 78 | 79 | void undampenImpl(); 80 | 81 | void startHalfLifeTimer(); 82 | void startMaxSuppressLimitTimer(); 83 | void stopMaxSuppressLimitTimer(); 84 | void stopHalfLifeTimer(); 85 | 86 | private: 87 | folly::EventBase* evb_{nullptr}; 88 | unsigned int history_{0}; 89 | bool dampened_{false}; 90 | std::unique_ptr halfLifeTimer_{nullptr}; 91 | std::unique_ptr maxSuppressLimitTimer_{nullptr}; 92 | const unsigned int penalty_; 93 | const unsigned int suppressLimit_; 94 | const unsigned int reuseLimit_; 95 | const std::chrono::seconds halfLife_; 96 | const std::chrono::seconds maxSuppressLimit_; 97 | }; 98 | 99 | } // namespace fbmeshd 100 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/Socket.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "Socket.h" 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace fbmeshd { 16 | 17 | Socket::~Socket() { 18 | if (fd != -1) { 19 | if (::close(fd) != 0) { 20 | // TODO handle error 21 | } 22 | } 23 | } 24 | 25 | Socket::Result 26 | Socket::connect( 27 | const std::string& interface, 28 | const folly::SocketAddress& address, 29 | const std::chrono::seconds& socketTimeout) { 30 | if (fd != -1) { 31 | return {false, "in_use"}; 32 | } 33 | 34 | if ((fd = ::socket( 35 | address.getIPAddress().isV4() ? AF_INET : AF_INET6, 36 | SOCK_STREAM, 37 | 0)) == -1) { 38 | return {false, "socket"}; 39 | } 40 | 41 | int enable = 1; 42 | if (::setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) != 0) { 43 | return {false, "setsockopt_reuseaddr"}; 44 | } 45 | 46 | // Set socket as non-blocking 47 | int flags; 48 | if ((flags = ::fcntl(fd, F_GETFL, 0)) < 0) { 49 | return {false, "fcntl_getfl"}; 50 | } 51 | if (::fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { 52 | return {false, "fcntl_setfl"}; 53 | } 54 | 55 | // Bind socket to the specific interface 56 | if (::setsockopt( 57 | fd, 58 | SOL_SOCKET, 59 | SO_BINDTODEVICE, 60 | interface.c_str(), 61 | interface.size()) != 0) { 62 | return {false, "setsockopt_bindtodevice"}; 63 | } 64 | 65 | // Set destination for the connect 66 | sockaddr_storage addr; 67 | auto addr_len = address.getAddress(&addr); 68 | 69 | // Attempt connection 70 | if (::connect(fd, reinterpret_cast(&addr), addr_len) == 0) { 71 | return {true, ""}; 72 | } 73 | 74 | if (errno != EINPROGRESS) { 75 | return {false, "not_einprogress"}; 76 | } 77 | 78 | // Connection is in progress, wait for timeout 79 | fd_set writefds; 80 | FD_ZERO(&writefds); 81 | FD_SET(fd, &writefds); 82 | 83 | timeval timeout; 84 | timeout.tv_sec = socketTimeout.count(); 85 | timeout.tv_usec = 0; 86 | 87 | if (::select(fd + 1, nullptr, &writefds, nullptr, &timeout) == 0) { 88 | return {false, "timeout"}; 89 | } 90 | 91 | int err; 92 | socklen_t err_len{sizeof(err)}; 93 | if (::getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &err_len) != 0) { 94 | return {false, "getsockopt_error"}; 95 | } 96 | 97 | if (err == 0) { 98 | return {true, ""}; 99 | } else { 100 | return {false, "err_non_zero"}; 101 | } 102 | } 103 | 104 | } // namespace fbmeshd 105 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/Socket.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace fbmeshd { 16 | 17 | // This is a wrapper class around the posix socket calls. Its very simply right 18 | // now as it just has one use case so it could be improved lot in the future. 19 | class Socket final { 20 | public: 21 | struct Result { 22 | bool success; 23 | std::string errorMsg; 24 | }; 25 | 26 | Socket() = default; 27 | ~Socket(); 28 | Socket(const Socket&) = delete; 29 | Socket& operator=(const Socket&) = delete; 30 | Socket(Socket&&) = delete; 31 | Socket& operator=(Socket&&) = delete; 32 | 33 | Result connect( 34 | const std::string& interface, 35 | const folly::SocketAddress& address, 36 | const std::chrono::seconds& socketTimeout); 37 | 38 | private: 39 | int fd{-1}; 40 | }; 41 | 42 | } // namespace fbmeshd 43 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/StatsClient.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "StatsClient.h" 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace fbmeshd { 18 | 19 | // Number of buckets to use for folly::BucketedTimeSeries 20 | static const uint64_t kTsBuckets{60}; 21 | 22 | // Statically defined levels for multi level timeseries. 23 | static const std::vector kLevelDurations = { 24 | std::chrono::seconds(60), // One minute 25 | std::chrono::seconds(600), // Ten minutes 26 | std::chrono::seconds(3600), // One hour 27 | std::chrono::seconds(0), // All time 28 | }; 29 | 30 | StatsClient::StatsClient() : stats_{{}}, types_{{}} {} 31 | 32 | void StatsClient::addStatValue( 33 | std::string const& key, 34 | int64_t value, 35 | StatsType type) { 36 | VLOG(8) << folly::sformat("StatsClient::{}()", __func__); 37 | 38 | auto it = stats_.find(key); 39 | if (it == stats_.end()) { 40 | VLOG(8) << folly::sformat("Initializing stats entry for {}...", key); 41 | 42 | // `stats_` is std::string -> folly::MultiLevelTimeSeries, and the 43 | // `emplace` function will create a new mapping on the fly, using 44 | // the parameters to std::forward_as_tuple as constructor parameters 45 | std::tie(it, std::ignore) = stats_.emplace( 46 | std::piecewise_construct, 47 | std::forward_as_tuple(key), 48 | std::forward_as_tuple( 49 | kTsBuckets, kLevelDurations.size(), kLevelDurations.data())); 50 | } 51 | 52 | types_.emplace(key, type); 53 | 54 | // Add the new value using the current time 55 | auto ts = std::chrono::duration_cast( 56 | std::chrono::steady_clock::now().time_since_epoch()); 57 | it->second.addValue(ts, value); 58 | } 59 | 60 | void StatsClient::incrementSumStat(const std::string& stat) { 61 | VLOG(8) << folly::sformat("StatsClient::{}() sum: {}", __func__, stat); 62 | addStatValue(stat, 1, StatsType::SUM); 63 | } 64 | 65 | void StatsClient::setAvgStat(const std::string& stat, int value) { 66 | VLOG(8) << folly::sformat("StatsClient::{}() avg: {}", __func__, stat); 67 | addStatValue(stat, value, StatsType::AVG); 68 | } 69 | 70 | const std::unordered_map StatsClient::getStats() { 71 | VLOG(8) << folly::sformat("StatsClient::{}()", __func__); 72 | std::unordered_map counters; 73 | 74 | for (auto& kv : stats_) { 75 | const std::string& key_ = kv.first; 76 | 77 | // Update the time series to reference against the current time 78 | auto ts = std::chrono::duration_cast( 79 | std::chrono::steady_clock::now().time_since_epoch()); 80 | kv.second.update(ts); 81 | 82 | // For each duration, calculate the stats for it 83 | for (size_t i = 0; i < kLevelDurations.size(); i++) { 84 | auto const& level = kv.second.getLevel(i); 85 | auto const interval = level.duration().count(); 86 | 87 | // Put the data together for the StatCounter thrift object, 88 | // which is the std::string and the associated value 89 | // 90 | // Example: fbmeshd_probe_wan_connectivity_success_sum_60 -> 59 91 | // Interpretation: In the last 60 seconds, the key 92 | // fbmeshd_probe_wan_connectivity_success was successful 59 times. 93 | auto type = types_.find(key_)->second; 94 | if (type == StatsType::SUM) { 95 | auto key = folly::sformat("{}.sum.{}", key_, interval); 96 | counters[key] = level.sum(); 97 | } else if (type == StatsType::AVG) { 98 | auto key = folly::sformat("{}.avg.{}", key_, interval); 99 | counters[key] = level.avg(); 100 | } else { 101 | VLOG(5) << "Unsupported export type."; 102 | } 103 | } 104 | } 105 | 106 | return counters; 107 | } 108 | 109 | } // namespace fbmeshd 110 | -------------------------------------------------------------------------------- /fbmeshd/gateway-connectivity-monitor/StatsClient.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace fbmeshd { 16 | 17 | enum StatsType { 18 | SUM = 0, 19 | AVG = 1, 20 | }; 21 | 22 | // This class is heavily inspired by fbzmq::StatsClient, the data structure 23 | // previously used here. In the process of removing dependency on fbzmq, this 24 | // slimmed down alternative was written in its place. 25 | class StatsClient final { 26 | public: 27 | StatsClient(); 28 | ~StatsClient() = default; 29 | StatsClient(const StatsClient&) = delete; 30 | StatsClient& operator=(const StatsClient&) = delete; 31 | StatsClient(StatsClient&&) = delete; 32 | StatsClient& operator=(StatsClient&&) = delete; 33 | 34 | void incrementSumStat(const std::string& stat); 35 | void setAvgStat(const std::string& stat, int value); 36 | 37 | const std::unordered_map getStats(); 38 | 39 | private: 40 | folly::F14FastMap< 41 | std::string, 42 | folly::MultiLevelTimeSeries> 43 | stats_; 44 | folly::F14FastMap types_; 45 | 46 | void addStatValue(std::string const& key, int64_t value, StatsType type); 47 | }; 48 | 49 | } // namespace fbmeshd 50 | -------------------------------------------------------------------------------- /fbmeshd/if/fbmeshd.thrift: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | namespace cpp2 fbmeshd.thrift 9 | namespace py3 fbmeshd 10 | 11 | exception MeshServiceError { 12 | 1: string message 13 | } (message = "message") 14 | 15 | //typedef list (cpp.type = "std::vector") MeshList 16 | 17 | typedef map 18 | (cpp.type = "std::unordered_map") PeerMetrics 19 | 20 | typedef i64 (cpp2.type = "uint64_t") MacAddress // network byte order 21 | typedef byte (cpp2.type = "uint8_t") u8 22 | typedef i32 (cpp2.type = "uint32_t") u32 23 | typedef i64 (cpp2.type = "uint64_t") u64 24 | 25 | struct Mesh { 26 | 4: i32 frequency 27 | 6: i32 channelWidth 28 | 7: i32 centerFreq1 29 | 12: optional i32 centerFreq2 30 | 14: optional i32 txPower 31 | } 32 | 33 | struct MpathEntry { 34 | 1: MacAddress dest 35 | 2: MacAddress nextHop 36 | 3: u64 sn 37 | 4: u32 metric 38 | 5: u64 expTime 39 | 6: u32 nextHopMetric 40 | 7: u8 hopCount 41 | 8: bool isRoot 42 | 9: bool isGate 43 | } 44 | 45 | struct StatCounter { 46 | 1: string key 47 | 2: i64 value 48 | } 49 | 50 | service MeshService { 51 | list getPeers(1: string ifName) 52 | throws (1: MeshServiceError error) 53 | 54 | PeerMetrics getMetrics(1: string ifName) 55 | throws (1: MeshServiceError error) 56 | 57 | Mesh getMesh(1: string ifName) 58 | throws (1: MeshServiceError error) 59 | 60 | list dumpStats() 61 | 62 | list dumpMpath(); 63 | } 64 | 65 | struct MeshPathFramePANN { 66 | 1: MacAddress origAddr 67 | 2: u64 origSn 68 | 3: u8 hopCount 69 | 4: u8 ttl 70 | 6: MacAddress targetAddr 71 | 7: u32 metric 72 | 8: bool isGate 73 | 9: bool replyRequested 74 | } 75 | 76 | /* 77 | * rnl thrift objects 78 | */ 79 | 80 | enum MplsActionCode { 81 | PUSH = 0 82 | SWAP = 1 83 | PHP = 2 # Pen-ultimate hop popping => POP and FORWARD 84 | POP_AND_LOOKUP = 3 85 | } 86 | 87 | const map protocolIdtoPriority = {99:10, 253:20, 64:11} 88 | const i16 kUnknownProtAdminDistance = 255 89 | -------------------------------------------------------------------------------- /fbmeshd/linkstatsd/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2004-present, Facebook, Inc. 3 | All rights reserved. 4 | 5 | This source code is licensed under the BSD-style license found in the 6 | LICENSE file in the root directory of this source tree. An additional grant 7 | of patent rights can be found in the PATENTS file in the same directory. 8 | """ 9 | -------------------------------------------------------------------------------- /fbmeshd/linkstatsd/main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2004-present, Facebook, Inc. 3 | All rights reserved. 4 | """ 5 | # @lint-ignore-every MYPY 6 | 7 | import argparse 8 | import logging 9 | 10 | from magma.common.sdwatchdog import SDWatchdog 11 | from magma.common.service import MagmaService 12 | from wifi.protos.mconfig import wifi_mconfigs_pb2 13 | 14 | from .collector import LinkstatsCollector 15 | from .state_manager import NetworkStateManager 16 | 17 | 18 | def create_parser() -> argparse.ArgumentParser: 19 | parser = argparse.ArgumentParser( 20 | "Linkstatsd for gathering key/value metrics and status metadata" 21 | ) 22 | parser.add_argument("-v", "--verbose", action="store_true", help="Debug output") 23 | return parser 24 | 25 | 26 | def main(): 27 | """ 28 | Main co-routine for linkstatsd 29 | :return: None 30 | """ 31 | parser = create_parser() 32 | args = parser.parse_args() 33 | 34 | # set up logging 35 | logging.basicConfig( 36 | level=logging.DEBUG if args.verbose else logging.INFO, 37 | format="[%(asctime)s %(levelname)s %(filename)s:%(lineno)d] %(message)s", 38 | ) 39 | 40 | # Get service config 41 | service = MagmaService("linkstatsd", wifi_mconfigs_pb2.Linkstatsd()) 42 | 43 | # Create stats collector 44 | collector = LinkstatsCollector(service.loop, service.config, service.mconfig) 45 | 46 | # Create network state manager 47 | state_mgr = NetworkStateManager(service.loop, service.config, service.mconfig) 48 | 49 | # Start state manager's state-updating loop 50 | state_mgr.start() 51 | 52 | # Register callback function to sync state with the cloud 53 | service.register_get_status_callback(state_mgr.get_state) 54 | 55 | # Start collector loop 56 | collector.start_collector() 57 | 58 | if SDWatchdog.has_notify(): 59 | # Create systemd watchdog 60 | sdwatchdog = SDWatchdog([collector, state_mgr], update_status=True) 61 | # Start watchdog loop 62 | service.loop.create_task(sdwatchdog.run()) 63 | 64 | # Run the service loop 65 | service.run() 66 | 67 | # Cleanup the service 68 | service.close() 69 | 70 | 71 | if __name__ == "__main__": 72 | main() 73 | -------------------------------------------------------------------------------- /fbmeshd/nl/GenericNetlinkCallbackHandle.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | namespace fbmeshd { 13 | 14 | using GenericNetlinkCallbackHandle = 15 | NetlinkCallbackHandle; 16 | 17 | } // namespace fbmeshd 18 | -------------------------------------------------------------------------------- /fbmeshd/nl/GenericNetlinkFamily.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "GenericNetlinkFamily.h" 9 | 10 | #include 11 | 12 | using namespace fbmeshd; 13 | 14 | const GenericNetlinkFamily& 15 | GenericNetlinkFamily::NL80211() { 16 | static const GenericNetlinkFamily nl80211{"nl80211"}; 17 | return nl80211; 18 | } 19 | 20 | const GenericNetlinkFamily& 21 | GenericNetlinkFamily::NLCTRL() { 22 | static const GenericNetlinkFamily nlctrl{"nlctrl"}; 23 | return nlctrl; 24 | } 25 | 26 | GenericNetlinkFamily::GenericNetlinkFamily(std::string family) 27 | : family_{family} {} 28 | 29 | GenericNetlinkFamily::operator int() const { 30 | if (!familyId_.has_value()) { 31 | familyId_ = GenericNetlinkSocket{}.resolveGenericNetlinkFamily(family_); 32 | } 33 | return *familyId_; 34 | } 35 | -------------------------------------------------------------------------------- /fbmeshd/nl/GenericNetlinkFamily.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | /** 17 | * Holds a list of Generic Netlink Family IDs 18 | * The family ID gets resolved on the first invocation of operator int() on 19 | * any family name; 20 | */ 21 | class GenericNetlinkFamily { 22 | public: 23 | static const GenericNetlinkFamily& NL80211(); 24 | static const GenericNetlinkFamily& NLCTRL(); 25 | 26 | explicit GenericNetlinkFamily(std::string family); 27 | 28 | GenericNetlinkFamily(const GenericNetlinkFamily&) = delete; 29 | 30 | explicit operator int() const; 31 | 32 | private: 33 | std::string family_; 34 | mutable folly::Optional familyId_; 35 | }; 36 | 37 | } // namespace fbmeshd 38 | -------------------------------------------------------------------------------- /fbmeshd/nl/GenericNetlinkMessage.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | #include // @manual 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace fbmeshd { 18 | 19 | /* 20 | * Generic Netlink message 21 | */ 22 | class GenericNetlinkMessage : public NetlinkMessage { 23 | public: 24 | explicit GenericNetlinkMessage(nl_msg* msg) : NetlinkMessage(msg) {} 25 | 26 | explicit GenericNetlinkMessage( 27 | const GenericNetlinkFamily& family, uint8_t cmd, int flags = 0) 28 | : NetlinkMessage() { 29 | genlmsg_put( 30 | msg_, 31 | NL_AUTO_PORT, 32 | NL_AUTO_SEQ, 33 | static_cast(family), 34 | 0, 35 | flags | NLM_F_ACK, 36 | cmd, 37 | 0); 38 | } 39 | 40 | GenericNetlinkMessage(const GenericNetlinkMessage&) = delete; 41 | GenericNetlinkMessage& operator=(const GenericNetlinkMessage&) = delete; 42 | 43 | genlmsghdr* 44 | getGenericHeader() const { 45 | return genlmsg_hdr(getHeader()); 46 | } 47 | 48 | template 49 | auto 50 | getAttributes() const { 51 | const auto gnlh = getGenericHeader(); 52 | return TabularNetlinkAttribute{genlmsg_attrdata(gnlh, 0), 53 | genlmsg_attrlen(gnlh, 0)}; 54 | } 55 | }; 56 | 57 | } // namespace fbmeshd 58 | -------------------------------------------------------------------------------- /fbmeshd/nl/GenericNetlinkSocket.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | #include // @manual 12 | #include // @manual 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | namespace fbmeshd { 19 | 20 | /** 21 | * Netlink wrapper for a generic nl_sock 22 | */ 23 | class GenericNetlinkSocket : public NetlinkSocket { 24 | public: 25 | GenericNetlinkSocket() : NetlinkSocket() { 26 | int err = genl_connect(sock_); 27 | CHECK_EQ(err, 0) << nl_geterror(err); 28 | 29 | setBufferSize(8192, 8192); 30 | } 31 | 32 | private: 33 | int 34 | resolveGenericNetlinkFamily(const std::string& name) { 35 | int id = genl_ctrl_resolve(sock_, name.c_str()); 36 | LOG_IF(ERROR, id < 0) << "could not resolve family " << name; 37 | return id; 38 | } 39 | 40 | friend class GenericNetlinkFamily; 41 | }; 42 | 43 | } // namespace fbmeshd 44 | -------------------------------------------------------------------------------- /fbmeshd/nl/NestedNetlinkAttribute.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | /** 17 | * A Netlink attribute that contains nested attributes 18 | * 19 | * This class should be used when you want to iterate over the nested attributes 20 | * for a nlattr, by means of an iterator. 21 | * 22 | * Before: 23 | * nlattr* nl_mode; 24 | * int rem_mode; 25 | * nla_for_each_nested( 26 | * nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode) { 27 | * ... 28 | * } 29 | * 30 | * After: 31 | * for (const auto& nl_mode : 32 | * NestedNetlinkAttribute{tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES]}) { 33 | * ... 34 | * } 35 | */ 36 | class NestedNetlinkAttribute { 37 | public: 38 | /** 39 | * Iterator to access nested attributes of this nlattr. 40 | * The end iterator is represented by a nullptr nlattr* attribute. 41 | */ 42 | struct iterator : std::iterator { 43 | iterator() = default; 44 | explicit iterator(nlattr* nla) 45 | : pos{static_cast(nla_data(nla))}, rem{nla_len(nla)} {} 46 | 47 | iterator& 48 | operator++() { 49 | pos = nla_next(pos, &rem); 50 | if (!nla_ok(pos, rem)) { 51 | pos = nullptr; 52 | } 53 | return *this; 54 | } 55 | 56 | iterator 57 | operator++(int) { 58 | iterator __tmp = *this; 59 | ++__tmp; 60 | return __tmp; 61 | } 62 | 63 | bool 64 | operator==(const iterator& other) const { 65 | return other.pos == pos; 66 | } 67 | 68 | bool 69 | operator!=(const iterator& other) const { 70 | return other.pos != pos; 71 | } 72 | 73 | nlattr* operator*() const { 74 | return pos; 75 | }; 76 | 77 | private: 78 | nlattr* pos{nullptr}; 79 | int rem; 80 | }; 81 | 82 | NestedNetlinkAttribute(nlattr* nlattrp) : nlattrp_{nlattrp} {} 83 | 84 | iterator 85 | begin() { 86 | return iterator{nlattrp_}; 87 | } 88 | 89 | iterator 90 | end() { 91 | return iterator{}; 92 | } 93 | 94 | private: 95 | nlattr* nlattrp_; 96 | }; 97 | 98 | } // namespace fbmeshd 99 | -------------------------------------------------------------------------------- /fbmeshd/nl/NetlinkCallbackHandle.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | #include // @manual 12 | 13 | #include 14 | 15 | #include 16 | 17 | #include 18 | 19 | namespace fbmeshd { 20 | 21 | /** 22 | * Netlink callback handle class, can be used to wrap different callbacks 23 | * associated with a netlink call 24 | */ 25 | template 26 | class NetlinkCallbackHandle { 27 | public: 28 | using CallbackFn = std::function; 29 | using ErrorCallbackFn = std::function; 30 | 31 | NetlinkCallbackHandle(nl_cb_kind kind = NL_CB_DEFAULT) 32 | : cb_{nl_cb_alloc(kind)} { 33 | CHECK_NOTNULL(cb_); 34 | } 35 | 36 | NetlinkCallbackHandle(nl_sock* sock) : cb_{nl_socket_get_cb(sock)} { 37 | CHECK_NOTNULL(cb_); 38 | } 39 | 40 | ~NetlinkCallbackHandle() { 41 | nl_cb_put(cb_); 42 | } 43 | 44 | NetlinkCallbackHandle(const NetlinkCallbackHandle&) = delete; 45 | 46 | void 47 | setErrorCallback(ErrorCallbackFn cbError) { 48 | cbError_ = cbError; 49 | CHECK_EQ(nl_cb_err(cb_, NL_CB_CUSTOM, &customErrorCallback, &cbError_), 0); 50 | } 51 | 52 | void 53 | setValidCallback(CallbackFn cbValid) { 54 | cbValid_ = cbValid; 55 | setCallback(cbValid_); 56 | } 57 | 58 | void 59 | setFinishCallback(CallbackFn cbFinish) { 60 | cbFinish_ = cbFinish; 61 | setCallback(cbFinish_); 62 | } 63 | 64 | void 65 | setAckCallback(CallbackFn cbAck) { 66 | cbAck_ = cbAck; 67 | setCallback(cbAck_); 68 | } 69 | 70 | explicit operator nl_cb*() const { 71 | return cb_; 72 | }; 73 | 74 | private: 75 | template 76 | void 77 | setCallback(CallbackFn& cb) { 78 | CHECK_EQ(nl_cb_set(cb_, type, NL_CB_CUSTOM, &customCallback, &cb), 0); 79 | } 80 | 81 | static int 82 | customCallback(nl_msg* msg, void* arg) { 83 | return (*static_cast(arg))(MessageType{msg}); 84 | } 85 | 86 | static int 87 | customErrorCallback(sockaddr_nl* nla, nlmsgerr* err, void* arg) { 88 | return (*static_cast(arg))(nla, err); 89 | } 90 | 91 | ErrorCallbackFn cbError_; 92 | CallbackFn cbValid_; 93 | CallbackFn cbFinish_; 94 | CallbackFn cbAck_; 95 | nl_cb* cb_; 96 | }; 97 | 98 | } // namespace fbmeshd 99 | -------------------------------------------------------------------------------- /fbmeshd/nl/NetlinkMessage.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | /* 17 | * Netlink message class which is a wrapper for a nl_msg*. 18 | */ 19 | class NetlinkMessage { 20 | public: 21 | NetlinkMessage() : msg_{nlmsg_alloc()} { 22 | CHECK_NOTNULL(msg_); 23 | } 24 | 25 | explicit NetlinkMessage(nl_msg* msg) : msg_{msg} { 26 | nlmsg_get(msg_); 27 | } 28 | 29 | NetlinkMessage(const NetlinkMessage&) = delete; 30 | NetlinkMessage& operator=(const NetlinkMessage&) = delete; 31 | 32 | ~NetlinkMessage() { 33 | nlmsg_free(msg_); 34 | } 35 | 36 | operator nl_msg*() const { 37 | return msg_; 38 | }; 39 | 40 | nlmsghdr* 41 | getHeader() const { 42 | return nlmsg_hdr(msg_); 43 | } 44 | 45 | protected: 46 | nl_msg* msg_; 47 | }; 48 | 49 | } // namespace fbmeshd 50 | -------------------------------------------------------------------------------- /fbmeshd/nl/TabularNetlinkAttribute.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | #include // @manual 12 | #include // @manual 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | namespace fbmeshd { 21 | 22 | /** 23 | * A Netlink attribute with data fields 24 | * 25 | * This class should be used when the nlattr is a key-val map 26 | * 27 | * Before: 28 | * std::array tb_band; 29 | * nla_parse( 30 | * tb_band.data(), 31 | * NL80211_BAND_ATTR_MAX, 32 | * (nlattr*)nla_data(nl_band), 33 | * nla_len(nl_band), 34 | * nullptr); 35 | * std::cout << tb_band[NL80211_BAND_ATTR_HT_MCS_SET]; 36 | * 37 | * After: 38 | * TabularNetlinkAttribute tb_band{nl_band}; 39 | * std::cout << tb_band[NL80211_BAND_ATTR_HT_MCS_SET]; 40 | */ 41 | template 42 | class TabularNetlinkAttribute { 43 | private: 44 | explicit TabularNetlinkAttribute( 45 | nlattr* head, int len, const nla_policy* policy) { 46 | nla_parse( 47 | tb_attr_.data(), size, head, len, const_cast(policy)); 48 | } 49 | 50 | explicit TabularNetlinkAttribute(nlattr* nlattrp, const nla_policy* policy) 51 | : TabularNetlinkAttribute( 52 | static_cast(nla_data(nlattrp)), nla_len(nlattrp), policy) { 53 | } 54 | 55 | public: 56 | explicit TabularNetlinkAttribute( 57 | nlattr* head, int len, const std::array& policy) 58 | : TabularNetlinkAttribute(head, len, policy.data()) {} 59 | explicit TabularNetlinkAttribute(nlattr* head, int len) 60 | : TabularNetlinkAttribute(head, len, nullptr) {} 61 | 62 | explicit TabularNetlinkAttribute( 63 | nlattr* nlattrp, const std::array& policy) 64 | : TabularNetlinkAttribute(nlattrp, policy.data()) {} 65 | explicit TabularNetlinkAttribute(nlattr* nlattrp) 66 | : TabularNetlinkAttribute(nlattrp, nullptr) {} 67 | 68 | nlattr* operator[](size_t key) const { 69 | return tb_attr_.at(key); 70 | } 71 | 72 | nlattr* 73 | at(size_t key) const { 74 | const auto ret = operator[](key); 75 | if (FOLLY_UNLIKELY(ret == nullptr)) { 76 | throw std::out_of_range("netlink attribute doesn't exist"); 77 | } 78 | return ret; 79 | } 80 | 81 | private: 82 | std::array tb_attr_; 83 | }; 84 | 85 | } // namespace fbmeshd 86 | -------------------------------------------------------------------------------- /fbmeshd/notifier/Notifier.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2004-present Facebook. All Rights Reserved. 2 | 3 | #include "fbmeshd/notifier/Notifier.h" 4 | 5 | #ifdef ENABLE_SYSTEMD_NOTIFY 6 | #include // @manual 7 | #endif 8 | 9 | #include 10 | #include 11 | 12 | namespace fbmeshd { 13 | 14 | Notifier::Notifier(folly::EventBase* evb, std::chrono::milliseconds interval) { 15 | (void)evb; 16 | (void)interval; 17 | #ifdef ENABLE_SYSTEMD_NOTIFY 18 | uint64_t watchdogEnv{0}; 19 | int status{0}; 20 | // Always expect the watchdog to be set if systemd is here. 21 | CHECK_GE((status = sd_watchdog_enabled(0, &watchdogEnv)), 0) 22 | << "Problem when fetching systemd watchdog"; 23 | if (status == 0) { 24 | return; 25 | } 26 | 27 | notifierTimer_ = folly::AsyncTimeout::make(*evb, [this, interval]() noexcept { 28 | doNotify(); 29 | notifierTimer_->scheduleTimeout(interval); 30 | }); 31 | notifierTimer_->scheduleTimeout(interval); 32 | 33 | VLOG(8) << folly::sformat( 34 | "Started timer to notify systemd every {} ms.", interval.count()); 35 | #endif 36 | } 37 | 38 | void 39 | Notifier::doNotify() { 40 | #ifdef ENABLE_SYSTEMD_NOTIFY 41 | VLOG(8) << "Notifying the systemd watchdog..."; 42 | 43 | sd_notify(0, "WATCHDOG=1"); 44 | #endif 45 | } 46 | 47 | } // namespace fbmeshd 48 | -------------------------------------------------------------------------------- /fbmeshd/notifier/Notifier.h: -------------------------------------------------------------------------------- 1 | // Copyright 2004-present Facebook. All Rights Reserved. 2 | 3 | #pragma once 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | 10 | namespace fbmeshd { 11 | 12 | class Notifier { 13 | public: 14 | Notifier(folly::EventBase* evb, std::chrono::milliseconds interval); 15 | 16 | Notifier() = delete; 17 | ~Notifier() = default; 18 | Notifier(const Notifier&) = delete; 19 | Notifier(Notifier&&) = delete; 20 | Notifier& operator=(const Notifier&) = delete; 21 | Notifier& operator=(Notifier&&) = delete; 22 | 23 | private: 24 | void doNotify(); 25 | std::unique_ptr notifierTimer_; 26 | }; 27 | } // namespace fbmeshd 28 | -------------------------------------------------------------------------------- /fbmeshd/py/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # 3 | # Copyright (c) Facebook, Inc. and its affiliates. 4 | # 5 | # This source code is licensed under the MIT license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | # 8 | 9 | import os 10 | from subprocess import check_call 11 | 12 | from setuptools import find_packages, setup 13 | 14 | 15 | def create_package_list(base): 16 | """ 17 | Get all packages under the base directory 18 | """ 19 | 20 | return [base] + ["{}.{}".format(base, pkg) for pkg in find_packages(base)] 21 | 22 | 23 | def generate_thrift_files(): 24 | """ 25 | Get list of all thrift files (absolute path names) and then generate 26 | python definitions for all thrift files. 27 | """ 28 | 29 | current_dir = os.path.dirname(os.path.realpath(__file__)) 30 | thrift_dir = os.path.join(os.path.dirname(current_dir), "if") 31 | thrift_files = [x for x in os.listdir(thrift_dir) if x.endswith(".thrift")] 32 | 33 | for thrift_file in thrift_files: 34 | print("> Generating python definition for {}".format(thrift_file)) 35 | check_call( 36 | [ 37 | "thrift1", 38 | "--gen", 39 | "py", 40 | "--out", 41 | current_dir, 42 | os.path.join(thrift_dir, thrift_file), 43 | ] 44 | ) 45 | 46 | 47 | generate_thrift_files() 48 | 49 | setup(name="fbmeshd", version="1.0", packages=create_package_list("fbmeshd")) 50 | -------------------------------------------------------------------------------- /fbmeshd/route-update-monitor/RouteUpdateMonitor.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include // @manual 11 | #include // @manual 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | namespace fbmeshd { 23 | 24 | class RouteUpdateMonitor final : public folly::EventHandler { 25 | // This class should never be copied; remove default copy/move 26 | RouteUpdateMonitor() = delete; 27 | RouteUpdateMonitor(const RouteUpdateMonitor&) = delete; 28 | RouteUpdateMonitor(RouteUpdateMonitor&&) = delete; 29 | RouteUpdateMonitor& operator=(const RouteUpdateMonitor&) = delete; 30 | RouteUpdateMonitor& operator=(RouteUpdateMonitor&&) = delete; 31 | 32 | public: 33 | RouteUpdateMonitor(folly::EventBase* evb, Nl80211Handler& nlHandler); 34 | ~RouteUpdateMonitor(); 35 | 36 | private: 37 | void handlerReady(uint16_t events) noexcept override; 38 | 39 | // called whenever the routing table is updated 40 | void processRouteUpdate(); 41 | 42 | // checks whether this node has an L3 route (aka connected to gate) 43 | FOLLY_NODISCARD bool hasDefaultRoute(); 44 | Nl80211Handler& nlHandler_; 45 | 46 | nl_sock* sock_; 47 | nl_sock* eventSock_; 48 | nl_cache* routeCache_; 49 | }; // RouteUpdateMonitor 50 | 51 | } // namespace fbmeshd 52 | -------------------------------------------------------------------------------- /fbmeshd/routing/MetricManager.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | 14 | namespace fbmeshd { 15 | 16 | class MetricManager { 17 | public: 18 | virtual ~MetricManager(){}; 19 | 20 | virtual std::unordered_map 21 | getLinkMetrics() { 22 | return {}; 23 | }; 24 | }; 25 | 26 | } // namespace fbmeshd 27 | -------------------------------------------------------------------------------- /fbmeshd/routing/MetricManager80211s.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace fbmeshd { 19 | 20 | class MetricManager80211s : public MetricManager { 21 | public: 22 | struct Metric { 23 | uint32_t ewmaMetric{0}; 24 | uint32_t reportedMetric{0}; 25 | uint32_t count{0}; 26 | }; 27 | 28 | MetricManager80211s( 29 | folly::EventBase* evb, 30 | std::chrono::milliseconds interval, 31 | Nl80211Handler& nlHandler, 32 | uint32_t ewmaFactor, 33 | uint32_t hysteresisFactor, 34 | uint32_t baseBitrate, 35 | double rssiWeight); 36 | 37 | // This class should never be copied; remove default copy/move 38 | MetricManager80211s() = delete; 39 | ~MetricManager80211s() override = default; 40 | MetricManager80211s(const MetricManager80211s&) = delete; 41 | MetricManager80211s(MetricManager80211s&&) = delete; 42 | MetricManager80211s& operator=(const MetricManager80211s&) = delete; 43 | MetricManager80211s& operator=(MetricManager80211s&&) = delete; 44 | 45 | uint32_t getLinkMetric(const StationInfo& sta); 46 | 47 | virtual std::unordered_map getLinkMetrics() 48 | override; 49 | 50 | private: 51 | void updateMetrics(); 52 | uint32_t bitrateToAirtime(uint32_t rate); 53 | uint32_t rssiToAirtime(int32_t rssi); 54 | 55 | folly::EventBase* evb_; 56 | Nl80211Handler& nlHandler_; 57 | std::unordered_map metrics_; 58 | uint32_t ewmaFactor_; 59 | uint32_t hysteresisFactor_; 60 | uint32_t baseBitrate_; 61 | double rssiWeight_; 62 | std::unique_ptr metricManagerTimer_; 63 | }; 64 | 65 | } // namespace fbmeshd 66 | -------------------------------------------------------------------------------- /fbmeshd/routing/PeriodicPinger.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "PeriodicPinger.h" 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include 17 | 18 | using namespace fbmeshd; 19 | 20 | PeriodicPinger::PeriodicPinger( 21 | folly::EventBase* evb, 22 | folly::IPAddressV6 dst, 23 | folly::IPAddressV6 src, 24 | std::chrono::milliseconds interval, 25 | const std::string& interface) 26 | : dst_{dst}, src_{src}, interface_{interface} { 27 | periodicPingerTimer_ = 28 | folly::AsyncTimeout::make(*evb, [this, interval]() noexcept { 29 | doPing(); 30 | periodicPingerTimer_->scheduleTimeout(interval); 31 | }); 32 | periodicPingerTimer_->scheduleTimeout(interval); 33 | } 34 | 35 | void 36 | PeriodicPinger::doPing() { 37 | VLOG(8) << folly::sformat("PeriodicPinger::{}()", __func__); 38 | auto sock = ::socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); 39 | CHECK_NE(sock, -1); 40 | 41 | icmp6_hdr icmpHeader; 42 | icmpHeader.icmp6_type = ICMP6_ECHO_REQUEST; 43 | icmpHeader.icmp6_code = 0; 44 | 45 | auto checksumOffset = offsetof(icmp6_hdr, icmp6_cksum); 46 | CHECK_EQ( 47 | ::setsockopt( 48 | sock, 49 | SOL_RAW, 50 | IPV6_CHECKSUM, 51 | &checksumOffset, 52 | sizeof(checksumOffset)), 53 | 0); 54 | 55 | const auto dstSockAddr = dst_.toSockAddr(); 56 | 57 | ::sendto( 58 | sock, 59 | &icmpHeader, 60 | sizeof(icmpHeader), 61 | 0, 62 | const_cast(reinterpret_cast(&dstSockAddr)), 63 | sizeof(dstSockAddr)); 64 | 65 | ::close(sock); 66 | } 67 | -------------------------------------------------------------------------------- /fbmeshd/routing/PeriodicPinger.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | namespace fbmeshd { 17 | 18 | class PeriodicPinger { 19 | public: 20 | PeriodicPinger( 21 | folly::EventBase* evb, 22 | folly::IPAddressV6 dst, 23 | folly::IPAddressV6 src, 24 | std::chrono::milliseconds interval, 25 | const std::string& interface); 26 | 27 | PeriodicPinger() = delete; 28 | ~PeriodicPinger() = default; 29 | PeriodicPinger(const PeriodicPinger&) = delete; 30 | PeriodicPinger(PeriodicPinger&&) = delete; 31 | PeriodicPinger& operator=(const PeriodicPinger&) = delete; 32 | PeriodicPinger& operator=(PeriodicPinger&&) = delete; 33 | 34 | private: 35 | void doPing(); 36 | 37 | folly::IPAddressV6 dst_; 38 | folly::IPAddressV6 src_; 39 | std::unique_ptr periodicPingerTimer_; 40 | const std::string& interface_; 41 | }; 42 | 43 | } // namespace fbmeshd 44 | -------------------------------------------------------------------------------- /fbmeshd/routing/SyncRoutes80211s.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace fbmeshd { 19 | 20 | class SyncRoutes80211s { 21 | public: 22 | SyncRoutes80211s( 23 | folly::EventBase* evb, 24 | Routing* routing, 25 | rnl::NetlinkSocket* netlinkSocket, 26 | folly::MacAddress nodeAddr, 27 | const std::string& interface); 28 | 29 | // This class should never be copied; remove default copy/move 30 | SyncRoutes80211s() = delete; 31 | ~SyncRoutes80211s() = default; 32 | SyncRoutes80211s(const SyncRoutes80211s&) = delete; 33 | SyncRoutes80211s(SyncRoutes80211s&&) = delete; 34 | SyncRoutes80211s& operator=(const SyncRoutes80211s&) = delete; 35 | SyncRoutes80211s& operator=(SyncRoutes80211s&&) = delete; 36 | 37 | private: 38 | void doSyncRoutes(); 39 | 40 | Routing* routing_; 41 | folly::MacAddress nodeAddr_; 42 | const std::string& interface_; 43 | 44 | std::unique_ptr syncRoutesTimer_; 45 | rnl::NetlinkSocket* netlinkSocket_; 46 | 47 | folly::Optional> currentGate_; 48 | bool isGateBeforeRouteSync_{false}; 49 | }; 50 | 51 | } // namespace fbmeshd 52 | -------------------------------------------------------------------------------- /fbmeshd/routing/UDPRoutingPacketTransport.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include "UDPRoutingPacketTransport.h" 9 | 10 | #include 11 | 12 | using namespace fbmeshd; 13 | 14 | UDPRoutingPacketTransport::UDPRoutingPacketTransport( 15 | folly::EventBase* evb, 16 | const std::string& interface, 17 | uint16_t port, 18 | int32_t tos) 19 | : evb_{evb}, 20 | interface_{interface}, 21 | serverSocket_{evb_}, 22 | clientSocket_{evb_} { 23 | evb_->runInEventBaseThread([this, port, tos]() { 24 | serverSocket_.bind(folly::SocketAddress{"::", port}); 25 | serverSocket_.addListener(evb_, this); 26 | serverSocket_.listen(); 27 | 28 | clientSocket_.bind(folly::SocketAddress("::", 0)); 29 | clientSocket_.setTrafficClass(tos); 30 | }); 31 | } 32 | 33 | void 34 | UDPRoutingPacketTransport::onDataAvailable( 35 | std::shared_ptr /* socket */, 36 | const folly::SocketAddress& client, 37 | std::unique_ptr data, 38 | #ifdef USE_ON_DATA_AVAILABLE 39 | bool /* truncated */, 40 | OnDataAvailableParams) noexcept { 41 | #else 42 | bool /* truncated */) noexcept { 43 | #endif 44 | if (receivePacketCallback_) { 45 | (*receivePacketCallback_)( 46 | *client.getIPAddress().asV6().getMacAddressFromLinkLocal(), 47 | std::move(data)); 48 | } 49 | } 50 | 51 | void 52 | UDPRoutingPacketTransport::sendPacket( 53 | folly::MacAddress da, std::unique_ptr buf) { 54 | evb_->runInEventBaseThread([this, da, buf = std::move(buf)]() { 55 | const auto destSockAddr = folly::SocketAddress{ 56 | da.isBroadcast() 57 | ? folly::IPAddressV6{folly::sformat("ff02::1%{}", interface_)} 58 | : folly::IPAddressV6{folly::sformat( 59 | "{}%{}", 60 | folly::IPAddressV6{folly::IPAddressV6::LINK_LOCAL, da}.str(), 61 | interface_)}, 62 | 6668}; 63 | clientSocket_.write(destSockAddr, std::move(buf)); 64 | }); 65 | } 66 | 67 | void 68 | UDPRoutingPacketTransport::setReceivePacketCallback( 69 | std::function)> cb) { 70 | if (evb_->isRunning()) { 71 | evb_->runImmediatelyOrRunInEventBaseThreadAndWait( 72 | [this, cb = std::move(cb)]() { receivePacketCallback_ = cb; }); 73 | } else { 74 | receivePacketCallback_ = cb; 75 | } 76 | } 77 | 78 | void 79 | UDPRoutingPacketTransport::resetReceivePacketCallback() { 80 | if (evb_->isRunning()) { 81 | evb_->runImmediatelyOrRunInEventBaseThreadAndWait( 82 | [this]() { receivePacketCallback_.reset(); }); 83 | } else { 84 | receivePacketCallback_.reset(); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /fbmeshd/routing/UDPRoutingPacketTransport.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #pragma once 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | namespace fbmeshd { 17 | 18 | class UDPRoutingPacketTransport : public folly::AsyncUDPServerSocket::Callback { 19 | public: 20 | UDPRoutingPacketTransport( 21 | folly::EventBase* evb, 22 | const std::string& interface, 23 | uint16_t port, 24 | int32_t tos); 25 | 26 | void sendPacket(folly::MacAddress da, std::unique_ptr buf); 27 | 28 | void setReceivePacketCallback( 29 | std::function)> cb); 30 | void resetReceivePacketCallback(); 31 | 32 | private: 33 | virtual void 34 | onListenStarted() noexcept override {} 35 | 36 | virtual void 37 | onListenStopped() noexcept override {} 38 | 39 | virtual void onDataAvailable( 40 | std::shared_ptr socket, 41 | const folly::SocketAddress& client, 42 | std::unique_ptr data, 43 | #ifdef USE_ON_DATA_AVAILABLE 44 | bool truncated, 45 | OnDataAvailableParams params) noexcept override; 46 | #else 47 | bool truncated) noexcept override; 48 | #endif 49 | 50 | folly::EventBase* evb_; 51 | 52 | const std::string& interface_; 53 | 54 | folly::AsyncUDPServerSocket serverSocket_; 55 | 56 | folly::AsyncUDPSocket clientSocket_; 57 | 58 | folly::Optional< 59 | std::function)>> 60 | receivePacketCallback_; 61 | }; 62 | 63 | } // namespace fbmeshd 64 | -------------------------------------------------------------------------------- /fbmeshd/tests/MockNl80211Handler.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | 12 | namespace fbmeshd { 13 | 14 | class MockNl80211Handler : public Nl80211HandlerInterface { 15 | public: 16 | MOCK_METHOD0(getPeers, std::vector()); 17 | MOCK_METHOD0(getStationsInfo, std::vector()); 18 | MOCK_METHOD1(setRssiThreshold, void(int32_t rssiThreshold)); 19 | MOCK_METHOD1(deleteStation, void(folly::MacAddress peer)); 20 | MOCK_METHOD0(lookupMeshNetif, NetInterface&()); 21 | }; 22 | 23 | } // namespace fbmeshd 24 | -------------------------------------------------------------------------------- /fbmeshd/tests/SocketTest.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) Facebook, Inc. and its affiliates. 3 | * 4 | * This source code is licensed under the MIT license found in the 5 | * LICENSE file in the root directory of this source tree. 6 | */ 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | using namespace fbmeshd; 18 | 19 | class SocketTest : public ::testing::Test { 20 | protected: 21 | static constexpr auto testInterface{"lo"}; 22 | static const folly::SocketAddress testAddress; 23 | static constexpr std::chrono::seconds testInterval{1}; 24 | }; 25 | 26 | const folly::SocketAddress SocketTest::testAddress{"127.0.0.1", 1337}; 27 | constexpr std::chrono::seconds SocketTest::testInterval; 28 | 29 | TEST_F(SocketTest, ConnectFailure) { 30 | Socket socket; 31 | Socket::Result result{ 32 | socket.connect(testInterface, testAddress, testInterval)}; 33 | EXPECT_FALSE(result.success); 34 | EXPECT_EQ( 35 | getuid() != 0 ? "setsockopt_bindtodevice" : "err_non_zero", 36 | result.errorMsg); 37 | } 38 | 39 | void 40 | waitUntilListening(const folly::SocketAddress& key) { 41 | std::string stdOut{}; 42 | do { 43 | folly::Subprocess ss{{"/usr/sbin/ss", std::string{"-tanpl"}}, 44 | folly::Subprocess::Options().pipeStdout()}; 45 | stdOut = ss.communicate().first; 46 | EXPECT_EQ(0, ss.wait().exitStatus()); 47 | } while (stdOut.find(key.describe()) == std::string::npos); 48 | } 49 | 50 | TEST_F(SocketTest, ConnectSuccess) { 51 | folly::Subprocess proc{{"/bin/nc", 52 | "-l", 53 | testAddress.getAddressStr(), 54 | folly::to(testAddress.getPort())}}; 55 | waitUntilListening(testAddress); 56 | 57 | { 58 | Socket socket; 59 | Socket::Result result{ 60 | socket.connect(testInterface, testAddress, testInterval)}; 61 | 62 | // This test is really only interesting when run as root. But this makes it 63 | // so it will at least pass otherwise. 64 | if (getuid() == 0) { 65 | EXPECT_TRUE(result.success); 66 | EXPECT_EQ("", result.errorMsg); 67 | } else { 68 | proc.terminate(); 69 | } 70 | } 71 | 72 | auto status = proc.wait(); 73 | EXPECT_TRUE(getuid() != 0 || status.exitStatus() == 0); 74 | } 75 | 76 | int 77 | main(int argc, char** argv) { 78 | ::google::InitGoogleLogging(argv[0]); 79 | ::testing::InitGoogleTest(&argc, argv); 80 | gflags::ParseCommandLineFlags(&argc, &argv, true); 81 | return RUN_ALL_TESTS(); 82 | } 83 | --------------------------------------------------------------------------------