mirror of
https://github.com/meteor/meteor.git
synced 2026-01-09 15:48:10 -05:00
Merge branch 'devel' into feature/docs-accounts-configurations
This commit is contained in:
14
.github/workflows/docs-deploy-main.yml
vendored
14
.github/workflows/docs-deploy-main.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Meteor Docs
|
||||
name: Meteor Docs Devel
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
@@ -8,30 +8,28 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: guide/site/
|
||||
working-directory: docs/
|
||||
if:
|
||||
contains('
|
||||
refs/heads/devel
|
||||
refs/heads/master
|
||||
', github.ref)
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 12.x
|
||||
cache: npm
|
||||
- name: Build the Guide
|
||||
- name: Build the Docs
|
||||
run: npm ci && npm run build
|
||||
- name: Deploy to Netlify for preview
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@v1.2.2
|
||||
with:
|
||||
publish-dir: './docs/public'
|
||||
production-branch: devel
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
deploy-message: Deploy from GitHub Actions ${{ github.event.pull_request.title }}
|
||||
deploy-message: Deploy from GitHub Actions devel
|
||||
netlify-config-path: './docs/netlify.toml'
|
||||
enable-pull-request-comment: false
|
||||
enable-commit-comment: false
|
||||
env:
|
||||
NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_GUIDE_SITE_ID }}
|
||||
NETLIFY_SITE_ID: ${{ secrets.NETLIFY_DOCS_SITE_ID }}
|
||||
|
||||
2
.github/workflows/docs.yml
vendored
2
.github/workflows/docs.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Meteor Docs
|
||||
name: Meteor Docs PR
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
|
||||
8
.github/workflows/guide-main-deploy.yml
vendored
8
.github/workflows/guide-main-deploy.yml
vendored
@@ -1,4 +1,4 @@
|
||||
name: Meteor Guide main deploy
|
||||
name: Meteor Guide Devel
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
@@ -12,7 +12,6 @@ jobs:
|
||||
if:
|
||||
contains('
|
||||
refs/heads/devel
|
||||
refs/heads/master
|
||||
', github.ref)
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -30,7 +29,6 @@ jobs:
|
||||
if:
|
||||
contains('
|
||||
refs/heads/devel
|
||||
refs/heads/master
|
||||
', github.ref)
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
@@ -39,13 +37,13 @@ jobs:
|
||||
node-version: 12.x
|
||||
- name: Build the Guide
|
||||
run: npm ci && npm run build
|
||||
- name: Deploy to Netlify for preview
|
||||
- name: Deploy to Netlify
|
||||
uses: nwtgck/actions-netlify@v1.2.2
|
||||
with:
|
||||
publish-dir: './guide/site/public'
|
||||
production-branch: devel
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
deploy-message: Deploy from GitHub Actions ${{ github.event.pull_request.title }}
|
||||
deploy-message: Deploy from GitHub Actions devel
|
||||
netlify-config-path: './guide/netlify.toml'
|
||||
enable-pull-request-comment: false
|
||||
enable-commit-comment: false
|
||||
|
||||
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -1,9 +1,6 @@
|
||||
[submodule "packages/non-core/blaze"]
|
||||
path = packages/non-core/blaze
|
||||
url = https://github.com/meteor/blaze.git
|
||||
[submodule "guide/site/themes/meteor"]
|
||||
path = guide/site/themes/meteor
|
||||
url = https://github.com/meteor/hexo-theme-meteor.git
|
||||
[submodule "docs/themes/meteor"]
|
||||
path = docs/themes/meteor
|
||||
url = https://github.com/meteor/hexo-theme-meteor.git
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## v2.5, UNRELEASED
|
||||
## v2.5, 2021-10-21
|
||||
|
||||
#### Highlights
|
||||
|
||||
|
||||
@@ -80,3 +80,4 @@ sudo rm /usr/local/bin/meteor
|
||||
```
|
||||
|
||||
On Windows, [read here](npm-packages/meteor-installer/README.md).
|
||||
|
||||
|
||||
@@ -34,4 +34,4 @@ Meteor is a full-stack JavaScript platform for developing modern web and mobile
|
||||
|
||||
{% oldRedirects %}
|
||||
|
||||
<!-- ABC: hidden comment for cache testing -->
|
||||
<!-- hidden comment to trigger a change again -->
|
||||
|
||||
@@ -80,3 +80,5 @@ The decisions made and practices outlined in the guide must necessarily be **opi
|
||||
An important function of the guide is to **shape future development** in the Meteor platform. By documenting best practices, the guide shines a spotlight on areas of the platform that could be better, easier, or more performant, and thus will be used to focus a lot of future platform choices.
|
||||
|
||||
Similarly, gaps in the platform highlighted by the guide can often be plugged by **community packages**; we hope that if you see an opportunity to improve the Meteor workflow by writing a package, that you take it! If you're not sure how best to design or architect your package, reach out on the forums and start a discussion.
|
||||
|
||||
<!-- hidden comment to trigger a change -->
|
||||
|
||||
Submodule guide/site/themes/meteor deleted from 66d0e57457
18
meteor
18
meteor
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
BUNDLE_VERSION=14.18.1.1
|
||||
BUNDLE_VERSION=14.18.1.2
|
||||
|
||||
# OS Check. Put here because here is where we download the precompiled
|
||||
# bundles that are arch specific.
|
||||
@@ -11,14 +11,18 @@ if [ "$UNAME" != "Linux" -a "$UNAME" != "Darwin" ] ; then
|
||||
fi
|
||||
|
||||
if [ "$UNAME" = "Darwin" ] ; then
|
||||
if [ "i386" != "$(uname -p)" -o "1" != "$(sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)" ] ; then
|
||||
if [ "arm64" == "$(uname -m)" ]; then
|
||||
ARCH="arm64"
|
||||
else
|
||||
if [ "i386" != "$(uname -p)" -o "1" != "$(sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)" ] ; then
|
||||
|
||||
# Can't just test uname -m = x86_64, because Snow Leopard can
|
||||
# return other values.
|
||||
echo "Only 64-bit Intel processors are supported at this time."
|
||||
exit 1
|
||||
# Can't just test uname -m = x86_64, because Snow Leopard can
|
||||
# return other values.
|
||||
echo "Only 64-bit and arm64 processors are supported at this time."
|
||||
exit 1
|
||||
fi
|
||||
ARCH="x86_64"
|
||||
fi
|
||||
ARCH="x86_64"
|
||||
elif [ "$UNAME" = "Linux" ] ; then
|
||||
ARCH="$(uname -m)"
|
||||
if [ "$ARCH" != "x86_64" ] ; then
|
||||
|
||||
@@ -10,9 +10,6 @@ MONGO_VERSION_64BIT=4.4.4
|
||||
MONGO_VERSION_32BIT=3.2.22
|
||||
NPM_VERSION=6.14.15
|
||||
|
||||
# If we built Node from source on Jenkins, this is the build number.
|
||||
NODE_BUILD_NUMBER=
|
||||
|
||||
if [ "$UNAME" == "Linux" ] ; then
|
||||
if [ "$ARCH" != "i686" -a "$ARCH" != "x86_64" ] ; then
|
||||
echo "Unsupported architecture: $ARCH"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'A user account system',
|
||||
version: '2.2.0-rc250.1',
|
||||
version: '2.2.0',
|
||||
});
|
||||
|
||||
Package.onUse(api => {
|
||||
|
||||
@@ -5,7 +5,7 @@ Package.describe({
|
||||
// 2.2.x in the future. The version was also bumped to 2.0.0 temporarily
|
||||
// during the Meteor 1.5.1 release process, so versions 2.0.0-beta.2
|
||||
// through -beta.5 and -rc.0 have already been published.
|
||||
version: '2.2.0-rc250.1',
|
||||
version: '2.2.0',
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'No-password login/sign-up support for accounts',
|
||||
version: '1.0.0-rc250.1',
|
||||
version: '1.0.0',
|
||||
});
|
||||
|
||||
Package.onUse(api => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Unstyled version of login widgets',
|
||||
version: '1.6.0-rc250.1',
|
||||
version: '1.6.0',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Update the client when new client code is available',
|
||||
version: '1.8.0-rc250.1',
|
||||
version: '1.8.0',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'ecmascript',
|
||||
version: '0.16.0-rc250.1',
|
||||
version: '0.16.0',
|
||||
summary: 'Compiler plugin that supports ES2015+ in all .js files',
|
||||
documentation: 'README.md',
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'hot-module-replacement',
|
||||
version: '0.4.0-rc250.1',
|
||||
version: '0.4.0',
|
||||
summary: 'Update code in development without reloading the page',
|
||||
documentation: 'README.md',
|
||||
debugOnly: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'The Meteor command-line tool',
|
||||
version: '2.5.0-rc250.1',
|
||||
version: '2.5.0',
|
||||
});
|
||||
|
||||
Package.includeTool();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'modules-runtime-hot',
|
||||
version: '0.14.0-rc250.1',
|
||||
version: '0.14.0',
|
||||
summary: 'Patches modules-runtime to support Hot Module Replacement',
|
||||
git: 'https://github.com/benjamn/install',
|
||||
documentation: 'README.md',
|
||||
|
||||
2
packages/react-fast-refresh/package.js
vendored
2
packages/react-fast-refresh/package.js
vendored
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'react-fast-refresh',
|
||||
version: '0.2.0-rc250.1',
|
||||
version: '0.2.0',
|
||||
summary: 'Automatically update React components with HMR',
|
||||
documentation: 'README.md',
|
||||
devOnly: true,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Manage the configuration for third-party services',
|
||||
version: '1.3.0-rc250.1',
|
||||
version: '1.3.0',
|
||||
});
|
||||
|
||||
Package.onUse(function(api) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
name: 'typescript',
|
||||
version: '4.4.0-rc250.1',
|
||||
version: '4.4.0',
|
||||
summary:
|
||||
'Compiler plugin that compiles TypeScript and ECMAScript in .ts and .tsx files',
|
||||
documentation: 'README.md',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Package.describe({
|
||||
summary: 'Serves a Meteor app over HTTP',
|
||||
version: '1.13.0-rc250.1',
|
||||
version: '1.13.0',
|
||||
});
|
||||
|
||||
Npm.depends({
|
||||
|
||||
55
scripts/admin/copy-dev-bundle-mac-m1-from-jenkins.sh
Executable file
55
scripts/admin/copy-dev-bundle-mac-m1-from-jenkins.sh
Executable file
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Requires awscli to be installed and an appropriate ~/.aws/config.
|
||||
# Usage:
|
||||
# scripts/admin/copy-dev-bundle-from-jenkins.sh [--prod] BUILDNUMBER
|
||||
# where BUILDNUMBER is the small integer Jenkins build number.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
cd "`dirname "$0"`"
|
||||
|
||||
arg=$1
|
||||
|
||||
TARGET="s3://com.meteor.static/test/"
|
||||
TEST=no
|
||||
if [ $# -ge 1 -a ${arg} = '--prod' ]; then
|
||||
shift
|
||||
arg=$1
|
||||
TARGET="s3://com.meteor.static/"
|
||||
else
|
||||
TEST=yes
|
||||
fi
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "usage: $0 [--prod] jenkins-build-number" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRNAME=$(aws s3 ls s3://com.meteor.jenkins/ | perl -nle 'print $1 if m!(dev-bundle-.+--'${arg}'--.+mac-m1)/!')
|
||||
|
||||
if [ -z "$DIRNAME" ]; then
|
||||
echo "build not found" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo Found build $DIRNAME
|
||||
|
||||
trap "echo Found surprising number of tarballs." EXIT
|
||||
# Check to make sure the proper number of each kind of file is there.
|
||||
aws s3 ls s3://com.meteor.jenkins/$DIRNAME/ | \
|
||||
perl -nle 'if (/\.tar\.gz/) { ++$TAR } else { die "something weird" } END { exit !($TAR == 1) }'
|
||||
|
||||
trap - EXIT
|
||||
|
||||
# This awful perl line means "print everything after the last whitespace".
|
||||
for FILE in $(aws s3 ls s3://com.meteor.jenkins/$DIRNAME/ | perl -nla -e 'print $F[-1]'); do
|
||||
if aws s3 ls $TARGET$FILE >/dev/null; then
|
||||
echo "$TARGET$FILE already exists (maybe from another branch?)"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
echo Copying to $TARGET
|
||||
aws s3 cp --acl public-read --recursive s3://com.meteor.jenkins/$DIRNAME/ $TARGET
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"track": "METEOR",
|
||||
"version": "2.4",
|
||||
"version": "2.5",
|
||||
"recommended": false,
|
||||
"official": true,
|
||||
"description": "The Official Meteor Distribution"
|
||||
|
||||
@@ -10,8 +10,6 @@ MONGO_VERSION_64BIT=4.4.4
|
||||
MONGO_VERSION_32BIT=3.2.22
|
||||
NPM_VERSION=6.14.15
|
||||
|
||||
# If we built Node from source on Jenkins, this is the build number.
|
||||
NODE_BUILD_NUMBER=
|
||||
|
||||
if [ "$UNAME" == "Linux" ] ; then
|
||||
if [ "$ARCH" != "i686" -a "$ARCH" != "x86_64" ] ; then
|
||||
@@ -26,18 +24,20 @@ if [ "$UNAME" == "Linux" ] ; then
|
||||
strip --remove-section=.comment --remove-section=.note $1
|
||||
}
|
||||
elif [ "$UNAME" == "Darwin" ] ; then
|
||||
SYSCTL_64BIT=$(sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)
|
||||
if [ "$ARCH" == "i386" -a "1" != "$SYSCTL_64BIT" ] ; then
|
||||
# some older macos returns i386 but can run 64 bit binaries.
|
||||
# Probably should distribute binaries built on these machines,
|
||||
# but it should be OK for users to run.
|
||||
ARCH="x86_64"
|
||||
fi
|
||||
if [ "$ARCH" != "arm64" ] ; then
|
||||
SYSCTL_64BIT=$(sysctl -n hw.cpu64bit_capable 2>/dev/null || echo 0)
|
||||
if [ "$ARCH" == "i386" -a "1" != "$SYSCTL_64BIT" ] ; then
|
||||
# some older macos returns i386 but can run 64 bit binaries.
|
||||
# Probably should distribute binaries built on these machines,
|
||||
# but it should be OK for users to run.
|
||||
ARCH="x86_64"
|
||||
fi
|
||||
|
||||
if [ "$ARCH" != "x86_64" ] ; then
|
||||
echo "Unsupported architecture: $ARCH"
|
||||
echo "Meteor only supports x86_64 for now."
|
||||
exit 1
|
||||
if [ "$ARCH" != "x86_64" ] ; then
|
||||
echo "Unsupported architecture: $ARCH"
|
||||
echo "Meteor only supports x86_64 for now."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
OS="macos"
|
||||
@@ -69,7 +69,11 @@ then
|
||||
fi
|
||||
elif [ "$UNAME" == "Darwin" ]
|
||||
then
|
||||
NODE_TGZ="node-v${NODE_VERSION}-darwin-x64.tar.gz"
|
||||
if [ "$ARCH" == "arm64" ] ; then
|
||||
NODE_TGZ="node-v${NODE_VERSION}-darwin-arm64.tar.gz"
|
||||
else
|
||||
NODE_TGZ="node-v${NODE_VERSION}-darwin-x64.tar.gz"
|
||||
fi
|
||||
else
|
||||
echo "Unknown architecture: $UNAME $ARCH"
|
||||
exit 1
|
||||
|
||||
@@ -28,7 +28,7 @@ mkdir node-build
|
||||
cd node-build
|
||||
|
||||
echo "Downloading Node from ${NODE_URL}"
|
||||
curl -sL "${NODE_URL}" | tar zx --strip-components 1
|
||||
curl -sL "${NODE_URL}" | tar -xz --strip 1
|
||||
|
||||
node_configure_flags=(
|
||||
# Enable the ICU internationalization library.
|
||||
@@ -40,15 +40,20 @@ then
|
||||
node_configure_flags+=('--debug')
|
||||
fi
|
||||
|
||||
# "make binary" includes DESTDIR and PORTABLE=1 options.
|
||||
TARBALL_NAME="node_${PLATFORM}_v${NODE_VERSION}"
|
||||
INSTALL_DIR="${DIR}/node-build/${TARBALL_NAME}"
|
||||
./configure --prefix="${INSTALL_DIR}"
|
||||
# Unsetting BUILD_DOWNLOAD_FLAGS allows the ICU download above to work.
|
||||
make -j4 binary \
|
||||
# -j8 from sysctl -n hw.ncpu
|
||||
make -j "$(sysctl -n hw.ncpu)" install \
|
||||
BUILD_DOWNLOAD_FLAGS= \
|
||||
RELEASE_URLBASE=https://nodejs.org/download/release/ \
|
||||
CONFIG_FLAGS="${node_configure_flags[@]+"${node_configure_flags[@]}"}"
|
||||
|
||||
TARBALL_PATH="${CHECKOUT_DIR}/node_${PLATFORM}_v${NODE_VERSION}.tar.gz"
|
||||
mv node-*.tar.gz "${TARBALL_PATH}"
|
||||
TARBALL_PATH="${CHECKOUT_DIR}/${TARBALL_NAME}.tar.gz"
|
||||
cd "$INSTALL_DIR"
|
||||
tar vcfz node.tar.gz .
|
||||
mv node.tar.gz "${TARBALL_PATH}"
|
||||
|
||||
cd "$DIR"
|
||||
rm -rf node-build
|
||||
|
||||
@@ -33,7 +33,7 @@ downloadNodeFromS3() {
|
||||
S3_TGZ="node_${UNAME}_${ARCH}_v${NODE_VERSION}.tar.gz"
|
||||
NODE_URL="https://${S3_HOST}/dev-bundle-node-${NODE_BUILD_NUMBER}/${S3_TGZ}"
|
||||
echo "Downloading Node from ${NODE_URL}" >&2
|
||||
curl "${NODE_URL}" | tar zx --strip-components 1
|
||||
curl "${NODE_URL}" | tar zx --strip 1
|
||||
}
|
||||
|
||||
downloadOfficialNode() {
|
||||
@@ -70,7 +70,13 @@ case $OS in
|
||||
;;
|
||||
esac
|
||||
|
||||
MONGO_NAME="mongodb-${OS}-${ARCH}-${MONGO_VERSION}"
|
||||
|
||||
if [ $OS = "macos" ] && [ "$(uname -m)" = "arm64" ] ; then
|
||||
MONGO_NAME="mongodb-${OS}-x86_64-${MONGO_VERSION}"
|
||||
else
|
||||
MONGO_NAME="mongodb-${OS}-${ARCH}-${MONGO_VERSION}"
|
||||
fi
|
||||
|
||||
MONGO_TGZ="${MONGO_NAME}.tgz"
|
||||
MONGO_URL="${MONGO_BASE_URL}/${MONGO_TGZ}"
|
||||
echo "Downloading Mongo from ${MONGO_URL}"
|
||||
|
||||
@@ -12,16 +12,19 @@ var Console = require('../console/console.js').Console;
|
||||
|
||||
// Given a Mongo URL, open an interative Mongo shell on this terminal
|
||||
// on that database.
|
||||
var runMongoShell = function (url) {
|
||||
var runMongoShell = function(url) {
|
||||
var mongoPath = files.pathJoin(
|
||||
files.getDevBundle(), 'mongodb', 'bin', 'mongo'
|
||||
files.getDevBundle(),
|
||||
'mongodb',
|
||||
'bin',
|
||||
'mongo'
|
||||
);
|
||||
// XXX mongo URLs are not real URLs (notably, the comma-separation for
|
||||
// multiple hosts). We've had a little better luck using the mongodb-uri npm
|
||||
// package.
|
||||
var mongoUrl = require('url').parse(url);
|
||||
var auth = mongoUrl.auth && mongoUrl.auth.split(':');
|
||||
var ssl = require('querystring').parse(mongoUrl.query).ssl === "true";
|
||||
var ssl = require('querystring').parse(mongoUrl.query).ssl === 'true';
|
||||
|
||||
var args = [];
|
||||
if (ssl) {
|
||||
@@ -35,8 +38,15 @@ var runMongoShell = function (url) {
|
||||
}
|
||||
args.push(mongoUrl.hostname + ':' + mongoUrl.port + mongoUrl.pathname);
|
||||
|
||||
child_process.spawn(files.convertToOSPath(mongoPath),
|
||||
args, { stdio: 'inherit' });
|
||||
// run with rosetta on mac m1
|
||||
if (process.platform === 'darwin' && process.arch === 'arm64') {
|
||||
args = ['-x86_64', mongoPath, ...args];
|
||||
mongoPath = 'arch';
|
||||
}
|
||||
|
||||
child_process.spawn(files.convertToOSPath(mongoPath), args, {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
};
|
||||
|
||||
// Start mongod with a dummy replSet and wait for it to listen.
|
||||
@@ -46,16 +56,21 @@ function spawnMongod(mongodPath, port, dbPath, replSetName) {
|
||||
mongodPath = files.convertToOSPath(mongodPath);
|
||||
dbPath = files.convertToOSPath(dbPath);
|
||||
|
||||
const args = [
|
||||
let args = [
|
||||
// nb: cli-test.sh and findMongoPids make strong assumptions about the
|
||||
// order of the arguments! Check them before changing any arguments.
|
||||
'--bind_ip', (process.env.METEOR_MONGO_BIND_IP || '127.0.0.1'),
|
||||
'--port', port,
|
||||
'--dbpath', dbPath,
|
||||
'--bind_ip',
|
||||
process.env.METEOR_MONGO_BIND_IP || '127.0.0.1',
|
||||
'--port',
|
||||
port,
|
||||
'--dbpath',
|
||||
dbPath,
|
||||
// Use an 8MB oplog rather than 256MB. Uses less space on disk and
|
||||
// initializes faster. (Not recommended for production!)
|
||||
'--oplogSize', '8',
|
||||
'--replSet', replSetName,
|
||||
'--oplogSize',
|
||||
'8',
|
||||
'--replSet',
|
||||
replSetName,
|
||||
'--noauth',
|
||||
|
||||
// Starting with version 4.0.8/4.1.10, MongoDB performs a step down
|
||||
@@ -67,7 +82,8 @@ function spawnMongod(mongodPath, port, dbPath, replSetName) {
|
||||
// parameter disables the step down. This will be the default for single-
|
||||
// node replica sets in MongoDB 4.3 (relevant commit: https://git.io/JeNkT),
|
||||
// so the parameter can be removed in the future.
|
||||
'--setParameter', 'waitForStepDownOnNonCommandShutdown=false'
|
||||
'--setParameter',
|
||||
'waitForStepDownOnNonCommandShutdown=false',
|
||||
];
|
||||
|
||||
// Use mmapv1 on 32bit platforms, as our binary doesn't support WT
|
||||
@@ -83,6 +99,11 @@ function spawnMongod(mongodPath, port, dbPath, replSetName) {
|
||||
args.push('--enableFreeMonitoring', 'off');
|
||||
}
|
||||
|
||||
// run with rosetta on mac m1
|
||||
if (process.platform === 'darwin' && process.arch === 'arm64') {
|
||||
args = ['-x86_64', mongodPath, ...args];
|
||||
mongodPath = 'arch';
|
||||
}
|
||||
return child_process.spawn(mongodPath, args, {
|
||||
// Apparently in some contexts, Mongo crashes if your locale isn't set up
|
||||
// right. I wasn't able to reproduce it, but many people on #4019
|
||||
@@ -90,10 +111,13 @@ function spawnMongod(mongodPath, port, dbPath, replSetName) {
|
||||
// they aren't set already. If these few aren't good enough, we'll at least
|
||||
// detect the locale error and print a link to #4019 (look for
|
||||
// `detectedErrors.badLocale` below).
|
||||
env: Object.assign({
|
||||
LANG: 'en_US.UTF-8',
|
||||
LC_ALL: 'en_US.UTF-8'
|
||||
}, process.env)
|
||||
env: Object.assign(
|
||||
{
|
||||
LANG: 'en_US.UTF-8',
|
||||
LC_ALL: 'en_US.UTF-8',
|
||||
},
|
||||
process.env
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -106,47 +130,52 @@ var findMongoPids;
|
||||
if (process.platform === 'win32') {
|
||||
// Windows doesn't have a ps equivalent that (reliably) includes the command
|
||||
// line, so approximate using the combined output of tasklist and netstat.
|
||||
findMongoPids = function (dbDir_unused, port) {
|
||||
findMongoPids = function(dbDir_unused, port) {
|
||||
var promise = fiberHelpers.makeFulfillablePromise();
|
||||
|
||||
child_process.exec('tasklist /fi "IMAGENAME eq mongod.exe"',
|
||||
function (error, stdout, stderr) {
|
||||
if (error) {
|
||||
var additionalInfo = JSON.stringify(error);
|
||||
if (error.code === 'ENOENT') {
|
||||
additionalInfo = "tasklist wasn't found on your system, it usually can be found at C:\\Windows\\System32\\.";
|
||||
child_process.exec('tasklist /fi "IMAGENAME eq mongod.exe"', function(
|
||||
error,
|
||||
stdout,
|
||||
stderr
|
||||
) {
|
||||
if (error) {
|
||||
var additionalInfo = JSON.stringify(error);
|
||||
if (error.code === 'ENOENT') {
|
||||
additionalInfo =
|
||||
"tasklist wasn't found on your system, it usually can be found at C:\\Windows\\System32\\.";
|
||||
}
|
||||
promise.reject(
|
||||
new Error("Couldn't run tasklist.exe: " + additionalInfo)
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
// Find the pids of all mongod processes
|
||||
var mongo_pids = [];
|
||||
stdout.split('\n').forEach(function(line) {
|
||||
var m = line.match(/^mongod.exe\s+(\d+) /);
|
||||
if (m) {
|
||||
mongo_pids[m[1]] = true;
|
||||
}
|
||||
promise.reject(
|
||||
new Error("Couldn't run tasklist.exe: " + additionalInfo)
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
// Find the pids of all mongod processes
|
||||
var mongo_pids = [];
|
||||
stdout.split('\n').forEach(function (line) {
|
||||
var m = line.match(/^mongod.exe\s+(\d+) /);
|
||||
if (m) {
|
||||
mongo_pids[m[1]] = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Now get the corresponding port numbers
|
||||
child_process.exec(
|
||||
'netstat -ano',
|
||||
{maxBuffer: 1024 * 1024 * 10},
|
||||
function (error, stdout, stderr) {
|
||||
// Now get the corresponding port numbers
|
||||
child_process.exec(
|
||||
'netstat -ano',
|
||||
{ maxBuffer: 1024 * 1024 * 10 },
|
||||
function(error, stdout, stderr) {
|
||||
if (error) {
|
||||
promise.reject(
|
||||
new Error("Couldn't run netstat -ano: " +
|
||||
JSON.stringify(error))
|
||||
new Error("Couldn't run netstat -ano: " + JSON.stringify(error))
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
var pids = [];
|
||||
stdout.split('\n').forEach(function (line) {
|
||||
var m = line.match(/^\s*TCP\s+\S+:(\d+)\s+\S+\s+LISTENING\s+(\d+)/);
|
||||
stdout.split('\n').forEach(function(line) {
|
||||
var m = line.match(
|
||||
/^\s*TCP\s+\S+:(\d+)\s+\S+\s+LISTENING\s+(\d+)/
|
||||
);
|
||||
if (m) {
|
||||
var found_pid = parseInt(m[2], 10);
|
||||
var found_pid = parseInt(m[2], 10);
|
||||
var found_port = parseInt(m[1], 10);
|
||||
|
||||
// We can't check the path app_dir so assume it always matches
|
||||
@@ -158,21 +187,23 @@ if (process.platform === 'win32') {
|
||||
pids.push({
|
||||
pid: found_pid,
|
||||
port: found_port,
|
||||
app_dir: null});
|
||||
app_dir: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
promise.resolve(pids);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
return promise.await();
|
||||
};
|
||||
} else {
|
||||
findMongoPids = function (dbDir, port) {
|
||||
findMongoPids = function(dbDir, port) {
|
||||
var promise = fiberHelpers.makeFulfillablePromise();
|
||||
|
||||
// 'ps ax' should be standard across all MacOS and Linux.
|
||||
@@ -208,7 +239,7 @@ if (process.platform === 'win32') {
|
||||
// If the child process output includes unicode, make sure it's
|
||||
// handled properly.
|
||||
const {
|
||||
LANG = "en_US.UTF-8",
|
||||
LANG = 'en_US.UTF-8',
|
||||
LC_ALL = LANG,
|
||||
LANGUAGE = LANG,
|
||||
// Remainder of process.env without above properties.
|
||||
@@ -229,40 +260,48 @@ if (process.platform === 'win32') {
|
||||
// (#2158).
|
||||
maxBuffer: 1024 * 1024 * 10,
|
||||
},
|
||||
function (error, stdout, stderr) {
|
||||
function(error, stdout, stderr) {
|
||||
if (error) {
|
||||
promise.reject(
|
||||
new Error("Couldn't run ps ax: " +
|
||||
JSON.stringify(error) + "; " +
|
||||
error.message)
|
||||
new Error(
|
||||
"Couldn't run ps ax: " +
|
||||
JSON.stringify(error) +
|
||||
'; ' +
|
||||
error.message
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
var ret = [];
|
||||
stdout.split('\n').forEach(function (line) {
|
||||
stdout.split('\n').forEach(function(line) {
|
||||
// Matches mongos we start. Note that this matches
|
||||
// 'fake-mongod' (our mongod stub for automated tests) as well
|
||||
// as 'mongod'.
|
||||
var m = line.match(/^\s*(\d+).+mongod .+--port (\d+) --dbpath (.+(?:\/|\\)db)/);
|
||||
var m = line.match(
|
||||
/^\s*(\d+).+mongod .+--port (\d+) --dbpath (.+(?:\/|\\)db)/
|
||||
);
|
||||
if (m && m.length === 4) {
|
||||
var foundPid = parseInt(m[1], 10);
|
||||
var foundPid = parseInt(m[1], 10);
|
||||
var foundPort = parseInt(m[2], 10);
|
||||
var foundPath = m[3];
|
||||
|
||||
if ( (! port || port === foundPort) &&
|
||||
(! dbDir || dbDir === foundPath)) {
|
||||
if (
|
||||
(!port || port === foundPort) &&
|
||||
(!dbDir || dbDir === foundPath)
|
||||
) {
|
||||
ret.push({
|
||||
pid: foundPid,
|
||||
port: foundPort,
|
||||
dbDir: foundPath
|
||||
dbDir: foundPath,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
promise.resolve(ret);
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return promise.await();
|
||||
};
|
||||
@@ -270,7 +309,7 @@ if (process.platform === 'win32') {
|
||||
|
||||
// See if mongo is running already. Yields. Returns the port that
|
||||
// mongo is running on or null if mongo is not running.
|
||||
var findMongoPort = function (dbDir) {
|
||||
var findMongoPort = function(dbDir) {
|
||||
var pids = findMongoPids(dbDir);
|
||||
|
||||
if (pids.length !== 1) {
|
||||
@@ -300,7 +339,7 @@ if (process.platform === 'win32') {
|
||||
// where we try to connect to a mongod that is not running, or a wrong
|
||||
// mongod if our current app is not running but there is a left-over file
|
||||
// lying around. This still can be better than always failing to connect.
|
||||
findMongoPort = function (dbPath) {
|
||||
findMongoPort = function(dbPath) {
|
||||
var mongoPort = null;
|
||||
|
||||
var portFile = files.pathJoin(dbPath, 'METEOR-PORT');
|
||||
@@ -314,36 +353,40 @@ if (process.platform === 'win32') {
|
||||
var net = require('net');
|
||||
|
||||
return new Promise(resolve => {
|
||||
var client = net.connect({
|
||||
port: mongoPort
|
||||
}, () => {
|
||||
// The server is running.
|
||||
client.end();
|
||||
resolve(mongoPort);
|
||||
});
|
||||
var client = net.connect(
|
||||
{
|
||||
port: mongoPort,
|
||||
},
|
||||
() => {
|
||||
// The server is running.
|
||||
client.end();
|
||||
resolve(mongoPort);
|
||||
}
|
||||
);
|
||||
client.on('error', () => resolve(null));
|
||||
}).catch(() => null).await();
|
||||
})
|
||||
.catch(() => null)
|
||||
.await();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
// Kill any mongos running on 'port'. Yields, and returns once they
|
||||
// are all dead. Throws an exception on failure.
|
||||
//
|
||||
// This is a big hammer for dealing with still running mongos, but
|
||||
// smaller hammers have failed before and it is getting tiresome.
|
||||
var findMongoAndKillItDead = function (port, dbPath) {
|
||||
var findMongoAndKillItDead = function(port, dbPath) {
|
||||
var pids = findMongoPids(null, port);
|
||||
|
||||
// Go through the list serially. There really should only ever be
|
||||
// at most one but we're not taking any chances.
|
||||
_.each(pids, function (processInfo) {
|
||||
_.each(pids, function(processInfo) {
|
||||
var pid = processInfo.pid;
|
||||
|
||||
// Send kill attempts and wait. First a SIGINT, then if it isn't
|
||||
// dead within 2 sec, SIGKILL. Check every 100ms to see if it's
|
||||
// dead.
|
||||
for (var attempts = 1; attempts <= 40; attempts ++) {
|
||||
for (var attempts = 1; attempts <= 40; attempts++) {
|
||||
var signal = 0;
|
||||
if (attempts === 1) {
|
||||
signal = 'SIGINT';
|
||||
@@ -365,19 +408,19 @@ var findMongoAndKillItDead = function (port, dbPath) {
|
||||
// XXX should actually catch this higher up and print a nice
|
||||
// error. foreseeable conditions should never result in exceptions
|
||||
// for the user.
|
||||
throw new Error("Can't kill running mongo (pid " + pid + ").");
|
||||
throw new Error("Can't kill running mongo (pid " + pid + ').');
|
||||
});
|
||||
|
||||
// If we had to kill mongod with SIGKILL, or on Windows where all calls to
|
||||
// `process.kill` work like SIGKILL, mongod will not have the opportunity to
|
||||
// close gracefully. Delete a lock file that may have been left over.
|
||||
var mongodLockFile = files.pathJoin(dbPath, "mongod.lock");
|
||||
var mongodLockFile = files.pathJoin(dbPath, 'mongod.lock');
|
||||
if (files.exists(mongodLockFile)) {
|
||||
files.unlink(mongodLockFile)
|
||||
files.unlink(mongodLockFile);
|
||||
}
|
||||
};
|
||||
|
||||
var StoppedDuringLaunch = function () {};
|
||||
var StoppedDuringLaunch = function() {};
|
||||
|
||||
// Starts a single instance of mongod, and configures it properly as a singleton
|
||||
// replica set. Yields. Returns once the mongod is successfully listening (or
|
||||
@@ -393,12 +436,15 @@ var StoppedDuringLaunch = function () {};
|
||||
// are killed (and onExit is then invoked). Also, the entirety of all three
|
||||
// databases is deleted before starting up. This is mode intended for testing
|
||||
// mongo failover, not for normal development or production use.
|
||||
var launchMongo = function (options) {
|
||||
var onExit = options.onExit || function () {};
|
||||
var launchMongo = function(options) {
|
||||
var onExit = options.onExit || function() {};
|
||||
|
||||
var noOplog = false;
|
||||
var mongod_path = files.pathJoin(
|
||||
files.getDevBundle(), 'mongodb', 'bin', 'mongod'
|
||||
files.getDevBundle(),
|
||||
'mongodb',
|
||||
'bin',
|
||||
'mongod'
|
||||
);
|
||||
var replSetName = 'meteor';
|
||||
|
||||
@@ -411,10 +457,14 @@ var launchMongo = function (options) {
|
||||
}
|
||||
|
||||
var fakeMongodCommand =
|
||||
process.platform === "win32" ? "fake-mongod.bat" : "fake-mongod";
|
||||
process.platform === 'win32' ? 'fake-mongod.bat' : 'fake-mongod';
|
||||
mongod_path = files.pathJoin(
|
||||
files.getCurrentToolsDir(), 'tools',
|
||||
'tests', 'fake-mongod', fakeMongodCommand);
|
||||
files.getCurrentToolsDir(),
|
||||
'tools',
|
||||
'tests',
|
||||
'fake-mongod',
|
||||
fakeMongodCommand
|
||||
);
|
||||
|
||||
// oplog support requires sending admin commands to mongod, so
|
||||
// it'd be hard to make fake-mongod support it.
|
||||
@@ -425,12 +475,12 @@ var launchMongo = function (options) {
|
||||
var stopped = false;
|
||||
var handle = {};
|
||||
var stopPromise = new Promise((resolve, reject) => {
|
||||
handle.stop = function () {
|
||||
handle.stop = function() {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
stopped = true;
|
||||
_.each(subHandles, function (handle) {
|
||||
_.each(subHandles, function(handle) {
|
||||
handle.stop();
|
||||
});
|
||||
|
||||
@@ -438,23 +488,26 @@ var launchMongo = function (options) {
|
||||
options.onStopped();
|
||||
}
|
||||
|
||||
reject(new StoppedDuringLaunch);
|
||||
reject(new StoppedDuringLaunch());
|
||||
};
|
||||
});
|
||||
|
||||
var yieldingMethod = function (object, methodName, ...args) {
|
||||
var yieldingMethod = function(object, methodName, ...args) {
|
||||
return Promise.race([
|
||||
stopPromise,
|
||||
new Promise((resolve, reject) => {
|
||||
object[methodName](...args, (err, res) => {
|
||||
err ? reject(err) : resolve(res);
|
||||
});
|
||||
})
|
||||
}),
|
||||
]).await();
|
||||
};
|
||||
|
||||
var launchOneMongoAndWaitForReadyForInitiate = function (dbPath, port,
|
||||
portFile) {
|
||||
var launchOneMongoAndWaitForReadyForInitiate = function(
|
||||
dbPath,
|
||||
port,
|
||||
portFile
|
||||
) {
|
||||
files.mkdir_p(dbPath, 0o755);
|
||||
|
||||
var proc = null;
|
||||
@@ -472,7 +525,7 @@ var launchMongo = function (options) {
|
||||
var portFileExists = false;
|
||||
var matchingPortFileExists = false;
|
||||
try {
|
||||
matchingPortFileExists = +(files.readFile(portFile)) === port;
|
||||
matchingPortFileExists = +files.readFile(portFile) === port;
|
||||
portFileExists = true;
|
||||
} catch (e) {
|
||||
if (!e || e.code !== 'ENOENT') {
|
||||
@@ -503,7 +556,7 @@ var launchMongo = function (options) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
_.each(dbFiles, function (dbFile) {
|
||||
_.each(dbFiles, function(dbFile) {
|
||||
if (/^local\./.test(dbFile)) {
|
||||
files.unlink(files.pathJoin(dbPath, dbFile));
|
||||
}
|
||||
@@ -527,10 +580,10 @@ var launchMongo = function (options) {
|
||||
proc = null;
|
||||
}
|
||||
}
|
||||
require("../tool-env/cleanup.js").onExit(stop);
|
||||
require('../tool-env/cleanup.js').onExit(stop);
|
||||
subHandles.push({ stop });
|
||||
|
||||
var procExitHandler = fiberHelpers.bindEnvironment(function (code, signal) {
|
||||
var procExitHandler = fiberHelpers.bindEnvironment(function(code, signal) {
|
||||
// Defang subHandle.stop().
|
||||
proc = null;
|
||||
|
||||
@@ -549,11 +602,13 @@ var launchMongo = function (options) {
|
||||
var replSetReady = false;
|
||||
|
||||
var maybeReadyToTalk;
|
||||
var readyToTalkPromise = new Promise(function (resolve) {
|
||||
maybeReadyToTalk = function () {
|
||||
if (resolve &&
|
||||
listening &&
|
||||
(noOplog || replSetReadyToBeInitiated || replSetReady)) {
|
||||
var readyToTalkPromise = new Promise(function(resolve) {
|
||||
maybeReadyToTalk = function() {
|
||||
if (
|
||||
resolve &&
|
||||
listening &&
|
||||
(noOplog || replSetReadyToBeInitiated || replSetReady)
|
||||
) {
|
||||
proc.stdout.removeListener('data', stdoutOnData);
|
||||
resolve();
|
||||
resolve = null;
|
||||
@@ -561,13 +616,10 @@ var launchMongo = function (options) {
|
||||
};
|
||||
});
|
||||
|
||||
var stopOrReadyPromise = Promise.race([
|
||||
stopPromise,
|
||||
readyToTalkPromise,
|
||||
]);
|
||||
var stopOrReadyPromise = Promise.race([stopPromise, readyToTalkPromise]);
|
||||
|
||||
var detectedErrors = {};
|
||||
var stdoutOnData = fiberHelpers.bindEnvironment(function (data) {
|
||||
var stdoutOnData = fiberHelpers.bindEnvironment(function(data) {
|
||||
// note: don't use "else ifs" in this, because 'data' can have multiple
|
||||
// lines
|
||||
if (
|
||||
@@ -601,15 +653,24 @@ var launchMongo = function (options) {
|
||||
}
|
||||
|
||||
// Running against a old mmapv1 engine, probably from pre-mongo-3.2 Meteor
|
||||
if (/created by the 'mmapv1' storage engine, so setting the active storage engine to 'mmapv1'/.test(data)) {
|
||||
if (
|
||||
/created by the 'mmapv1' storage engine, so setting the active storage engine to 'mmapv1'/.test(
|
||||
data
|
||||
)
|
||||
) {
|
||||
Console.warn();
|
||||
Console.warn('Your development database is using mmapv1, '
|
||||
+ 'the old, pre-MongoDB 3.0 database engine. '
|
||||
+ 'You should consider upgrading to Wired Tiger, the new engine. '
|
||||
+ 'The easiest way to do so in development is to run '
|
||||
+ Console.command('meteor reset') + '. '
|
||||
+ "If you'd like to migrate your database, please consult "
|
||||
+ Console.url('https://docs.mongodb.org/v3.0/release-notes/3.0-upgrade/'))
|
||||
Console.warn(
|
||||
'Your development database is using mmapv1, ' +
|
||||
'the old, pre-MongoDB 3.0 database engine. ' +
|
||||
'You should consider upgrading to Wired Tiger, the new engine. ' +
|
||||
'The easiest way to do so in development is to run ' +
|
||||
Console.command('meteor reset') +
|
||||
'. ' +
|
||||
"If you'd like to migrate your database, please consult " +
|
||||
Console.url(
|
||||
'https://docs.mongodb.org/v3.0/release-notes/3.0-upgrade/'
|
||||
)
|
||||
);
|
||||
Console.warn();
|
||||
}
|
||||
|
||||
@@ -622,29 +683,27 @@ var launchMongo = function (options) {
|
||||
|
||||
var stderrOutput = '';
|
||||
proc.stderr.setEncoding('utf8');
|
||||
proc.stderr.on('data', function (data) {
|
||||
proc.stderr.on('data', function(data) {
|
||||
stderrOutput += data;
|
||||
});
|
||||
|
||||
stopOrReadyPromise.await();
|
||||
};
|
||||
|
||||
|
||||
var initiateReplSetAndWaitForReady = function () {
|
||||
var initiateReplSetAndWaitForReady = function() {
|
||||
try {
|
||||
// Load mongo so we'll be able to talk to it.
|
||||
const {
|
||||
MongoClient,
|
||||
Server
|
||||
} = loadIsopackage('npm-mongo').NpmModuleMongodb;
|
||||
const { MongoClient, Server } = loadIsopackage(
|
||||
'npm-mongo'
|
||||
).NpmModuleMongodb;
|
||||
|
||||
// Connect to the intended primary and start a replset.
|
||||
const client = new MongoClient(
|
||||
new Server('127.0.0.1', options.port, {
|
||||
poolSize: 1,
|
||||
socketOptions: {
|
||||
connectTimeoutMS: 60000
|
||||
}
|
||||
connectTimeoutMS: 60000,
|
||||
},
|
||||
})
|
||||
);
|
||||
|
||||
@@ -659,17 +718,17 @@ var launchMongo = function (options) {
|
||||
_id: replSetName,
|
||||
version: 1,
|
||||
protocolVersion: 1,
|
||||
members: [{_id: 0, host: '127.0.0.1:' + options.port, priority: 100}]
|
||||
members: [{ _id: 0, host: '127.0.0.1:' + options.port, priority: 100 }],
|
||||
};
|
||||
|
||||
try {
|
||||
const config = yieldingMethod(db.admin(), "command", {
|
||||
const config = yieldingMethod(db.admin(), 'command', {
|
||||
replSetGetConfig: 1,
|
||||
}).config;
|
||||
|
||||
// If a replication set configuration already exists, it's
|
||||
// important that the new version number is greater than the old.
|
||||
if (config && _.has(config, "version")) {
|
||||
if (config && _.has(config, 'version')) {
|
||||
configuration.version = config.version + 1;
|
||||
}
|
||||
} catch (e) {}
|
||||
@@ -679,10 +738,14 @@ var launchMongo = function (options) {
|
||||
// could in theory become primary, and one of which can never be
|
||||
// primary.
|
||||
configuration.members.push({
|
||||
_id: 1, host: '127.0.0.1:' + (options.port + 1), priority: 5
|
||||
_id: 1,
|
||||
host: '127.0.0.1:' + (options.port + 1),
|
||||
priority: 5,
|
||||
});
|
||||
configuration.members.push({
|
||||
_id: 2, host: '127.0.0.1:' + (options.port + 2), priority: 0
|
||||
_id: 2,
|
||||
host: '127.0.0.1:' + (options.port + 2),
|
||||
priority: 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -697,7 +760,7 @@ var launchMongo = function (options) {
|
||||
force: true,
|
||||
});
|
||||
} else {
|
||||
throw Error("rs.initiate error: " + e.message);
|
||||
throw Error('rs.initiate error: ' + e.message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -710,20 +773,20 @@ var launchMongo = function (options) {
|
||||
// Wait until the primary is writable. If it isn't writable after one
|
||||
// minute, throw an error and report the replica set status.
|
||||
while (!stopped) {
|
||||
const { ismaster } = yieldingMethod(db.admin(), "command", {
|
||||
isMaster: 1
|
||||
const { ismaster } = yieldingMethod(db.admin(), 'command', {
|
||||
isMaster: 1,
|
||||
});
|
||||
|
||||
if (ismaster) {
|
||||
break;
|
||||
} else if (Date.now() - writableTimestamp > 60000) {
|
||||
const status = yieldingMethod(db.admin(), "command", {
|
||||
replSetGetStatus: 1
|
||||
const status = yieldingMethod(db.admin(), 'command', {
|
||||
replSetGetStatus: 1,
|
||||
});
|
||||
|
||||
throw new Error(
|
||||
"Primary not writable after one minute. Last replica set status: " +
|
||||
JSON.stringify(status)
|
||||
'Primary not writable after one minute. Last replica set status: ' +
|
||||
JSON.stringify(status)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -734,7 +797,7 @@ var launchMongo = function (options) {
|
||||
} catch (e) {
|
||||
// If the process has exited, we're doing another form of error
|
||||
// handling. No need to throw random low-level errors farther.
|
||||
if (!stopped || (e instanceof StoppedDuringLaunch)) {
|
||||
if (!stopped || e instanceof StoppedDuringLaunch) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
@@ -743,13 +806,13 @@ var launchMongo = function (options) {
|
||||
try {
|
||||
if (options.multiple) {
|
||||
var dbBasePath = files.pathJoin(options.projectLocalDir, 'dbs');
|
||||
_.each(_.range(3), function (i) {
|
||||
_.each(_.range(3), function(i) {
|
||||
// Did we get stopped (eg, by one of the processes exiting) by now? Then
|
||||
// don't start anything new.
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
var dbPath = files.pathJoin(options.projectLocalDir, 'dbs', ''+i);
|
||||
var dbPath = files.pathJoin(options.projectLocalDir, 'dbs', '' + i);
|
||||
launchOneMongoAndWaitForReadyForInitiate(dbPath, options.port + i);
|
||||
});
|
||||
if (!stopped) {
|
||||
@@ -763,7 +826,7 @@ var launchMongo = function (options) {
|
||||
initiateReplSetAndWaitForReady();
|
||||
if (!stopped) {
|
||||
// Write down that we configured the database properly.
|
||||
files.writeFile(portFile, ''+options.port);
|
||||
files.writeFile(portFile, '' + options.port);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -785,7 +848,7 @@ var launchMongo = function (options) {
|
||||
// logged, and onFailure is called.
|
||||
//
|
||||
// options: projectLocalDir, port, onFailure, multiple
|
||||
var MongoRunner = function (options) {
|
||||
var MongoRunner = function(options) {
|
||||
var self = this;
|
||||
self.projectLocalDir = options.projectLocalDir;
|
||||
self.port = options.port;
|
||||
@@ -812,11 +875,11 @@ Object.assign(MRp, {
|
||||
//
|
||||
// If the server fails to start for the first time (after a few
|
||||
// restarts), we'll print a message and give up.
|
||||
start: function () {
|
||||
start: function() {
|
||||
var self = this;
|
||||
|
||||
if (self.handle) {
|
||||
throw new Error("already running?");
|
||||
throw new Error('already running?');
|
||||
}
|
||||
|
||||
self._startOrRestart();
|
||||
@@ -832,8 +895,8 @@ Object.assign(MRp, {
|
||||
}
|
||||
|
||||
// Otherwise, wait for a successful _startOrRestart, or a failure.
|
||||
if (! self.resolveStartupPromise) {
|
||||
new Promise(function (resolve) {
|
||||
if (!self.resolveStartupPromise) {
|
||||
new Promise(function(resolve) {
|
||||
self.resolveStartupPromise = resolve;
|
||||
}).await();
|
||||
}
|
||||
@@ -850,16 +913,16 @@ Object.assign(MRp, {
|
||||
//
|
||||
// In case (a), self.handle will be the handle returned from launchMongo; in
|
||||
// case (b) self.handle will be null.
|
||||
_startOrRestart: function () {
|
||||
_startOrRestart: function() {
|
||||
var self = this;
|
||||
|
||||
if (self.handle) {
|
||||
throw new Error("already running?");
|
||||
throw new Error('already running?');
|
||||
}
|
||||
|
||||
var allowKilling = self.multiple || self.firstStart;
|
||||
self.firstStart = false;
|
||||
if (! allowKilling) {
|
||||
if (!allowKilling) {
|
||||
// If we're not going to try to kill an existing mongod first, then we
|
||||
// shouldn't annoy the user by telling it that we couldn't start up.
|
||||
self.suppressExitMessage = true;
|
||||
@@ -883,7 +946,7 @@ Object.assign(MRp, {
|
||||
}
|
||||
},
|
||||
|
||||
_exited: function (code, signal, stderr, detectedErrors) {
|
||||
_exited: function(code, signal, stderr, detectedErrors) {
|
||||
var self = this;
|
||||
|
||||
self.handle = null;
|
||||
@@ -899,12 +962,17 @@ Object.assign(MRp, {
|
||||
// wrong. If we didn't try to kill Mongo, we'll do that on the next
|
||||
// restart. Not killing it on the first try is important for speed,
|
||||
// since findMongoAndKillItDead is a very slow operation.
|
||||
if (! self.suppressExitMessage) {
|
||||
if (!self.suppressExitMessage) {
|
||||
// Print the last 20 lines of stderr.
|
||||
runLog.log(
|
||||
stderr.split('\n').slice(-20).join('\n') +
|
||||
"Unexpected mongo exit code " + code +
|
||||
(self.multiple ? "." : ". Restarting."));
|
||||
stderr
|
||||
.split('\n')
|
||||
.slice(-20)
|
||||
.join('\n') +
|
||||
'Unexpected mongo exit code ' +
|
||||
code +
|
||||
(self.multiple ? '.' : '. Restarting.')
|
||||
);
|
||||
}
|
||||
|
||||
// If we're in multiple mode, we never try to restart. That's to keep the
|
||||
@@ -918,21 +986,24 @@ Object.assign(MRp, {
|
||||
// when 5 seconds goes without a restart. (Note that by using a
|
||||
// timer instead of looking at the current date, we avoid getting
|
||||
// confused by time changes.)
|
||||
self.errorCount ++;
|
||||
self.errorCount++;
|
||||
if (self.errorTimer) {
|
||||
clearTimeout(self.errorTimer);
|
||||
}
|
||||
self.errorTimer = setTimeout(function () {
|
||||
self.errorTimer = setTimeout(function() {
|
||||
self.errorTimer = null;
|
||||
self.errorCount = 0;
|
||||
}, 5000);
|
||||
|
||||
if (self.errorCount < 3) {
|
||||
// Wait a second, then restart.
|
||||
self.restartTimer = setTimeout(fiberHelpers.bindEnvironment(function () {
|
||||
self.restartTimer = null;
|
||||
self._startOrRestart();
|
||||
}), 1000);
|
||||
self.restartTimer = setTimeout(
|
||||
fiberHelpers.bindEnvironment(function() {
|
||||
self.restartTimer = null;
|
||||
self._startOrRestart();
|
||||
}),
|
||||
1000
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -941,35 +1012,45 @@ Object.assign(MRp, {
|
||||
var explanation = MongoExitCodes[code];
|
||||
var message = "Can't start Mongo server.";
|
||||
|
||||
if (explanation && explanation.symbol === 'EXIT_UNCAUGHT' &&
|
||||
detectedErrors.freeSpace) {
|
||||
message += "\n\n" +
|
||||
"Looks like you are out of free disk space under .meteor/local.";
|
||||
if (
|
||||
explanation &&
|
||||
explanation.symbol === 'EXIT_UNCAUGHT' &&
|
||||
detectedErrors.freeSpace
|
||||
) {
|
||||
message +=
|
||||
'\n\n' +
|
||||
'Looks like you are out of free disk space under .meteor/local.';
|
||||
} else if (explanation) {
|
||||
message += "\n" + explanation.longText;
|
||||
message += '\n' + explanation.longText;
|
||||
} else if (process.platform === 'win32') {
|
||||
message += "\n\n" +
|
||||
"Check how to troubleshoot here " +
|
||||
"https://docs.meteor.com/windows.html#cant-start-mongo-server";
|
||||
message +=
|
||||
'\n\n' +
|
||||
'Check how to troubleshoot here ' +
|
||||
'https://docs.meteor.com/windows.html#cant-start-mongo-server';
|
||||
}
|
||||
|
||||
if (explanation && explanation.symbol === 'EXIT_NET_ERROR') {
|
||||
message += "\n\n" +
|
||||
"Check for other processes listening on port " + self.port + "\n" +
|
||||
"or other Meteor instances running in the same project.";
|
||||
message +=
|
||||
'\n\n' +
|
||||
'Check for other processes listening on port ' +
|
||||
self.port +
|
||||
'\n' +
|
||||
'or other Meteor instances running in the same project.';
|
||||
}
|
||||
|
||||
if (! explanation && /GLIBC/i.test(stderr)) {
|
||||
message += "\n\n" +
|
||||
"Looks like you are trying to run Meteor on an old Linux distribution.\n" +
|
||||
"Meteor on Linux requires glibc version 2.9 or above. Try upgrading your\n" +
|
||||
"distribution to the latest version.";
|
||||
if (!explanation && /GLIBC/i.test(stderr)) {
|
||||
message +=
|
||||
'\n\n' +
|
||||
'Looks like you are trying to run Meteor on an old Linux distribution.\n' +
|
||||
'Meteor on Linux requires glibc version 2.9 or above. Try upgrading your\n' +
|
||||
'distribution to the latest version.';
|
||||
}
|
||||
|
||||
if (detectedErrors.badLocale) {
|
||||
message += "\n\n" +
|
||||
"Looks like MongoDB doesn't understand your locale settings. See\n" +
|
||||
"https://github.com/meteor/meteor/issues/4019 for more details.";
|
||||
message +=
|
||||
'\n\n' +
|
||||
"Looks like MongoDB doesn't understand your locale settings. See\n" +
|
||||
'https://github.com/meteor/meteor/issues/4019 for more details.';
|
||||
}
|
||||
|
||||
runLog.log(message);
|
||||
@@ -977,7 +1058,7 @@ Object.assign(MRp, {
|
||||
},
|
||||
|
||||
// Idempotent
|
||||
stop: function () {
|
||||
stop: function() {
|
||||
var self = this;
|
||||
|
||||
if (self.shuttingDown) {
|
||||
@@ -995,7 +1076,7 @@ Object.assign(MRp, {
|
||||
}
|
||||
},
|
||||
|
||||
_allowStartupToReturn: function () {
|
||||
_allowStartupToReturn: function() {
|
||||
var self = this;
|
||||
if (self.resolveStartupPromise) {
|
||||
var resolve = self.resolveStartupPromise;
|
||||
@@ -1004,36 +1085,35 @@ Object.assign(MRp, {
|
||||
}
|
||||
},
|
||||
|
||||
_fail: function () {
|
||||
_fail: function() {
|
||||
var self = this;
|
||||
self.stop();
|
||||
self.onFailure && self.onFailure();
|
||||
self._allowStartupToReturn();
|
||||
},
|
||||
|
||||
_mongoHosts: function () {
|
||||
_mongoHosts: function() {
|
||||
var self = this;
|
||||
var ports = [self.port];
|
||||
if (self.multiple) {
|
||||
ports.push(self.port + 1, self.port + 2);
|
||||
}
|
||||
return _.map(ports, function (port) {
|
||||
return "127.0.0.1:" + port;
|
||||
}).join(",");
|
||||
return _.map(ports, function(port) {
|
||||
return '127.0.0.1:' + port;
|
||||
}).join(',');
|
||||
},
|
||||
|
||||
mongoUrl: function () {
|
||||
mongoUrl: function() {
|
||||
var self = this;
|
||||
return "mongodb://" + self._mongoHosts() + "/meteor";
|
||||
return 'mongodb://' + self._mongoHosts() + '/meteor';
|
||||
},
|
||||
|
||||
oplogUrl: function () {
|
||||
oplogUrl: function() {
|
||||
var self = this;
|
||||
return "mongodb://" + self._mongoHosts() + "/local";
|
||||
}
|
||||
return 'mongodb://' + self._mongoHosts() + '/local';
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
exports.runMongoShell = runMongoShell;
|
||||
exports.findMongoPort = findMongoPort;
|
||||
exports.MongoRunner = MongoRunner;
|
||||
|
||||
@@ -129,6 +129,7 @@ const utils = require('./utils');
|
||||
// Valid architectures that Meteor officially supports.
|
||||
export const VALID_ARCHITECTURES: Record<string, boolean> = {
|
||||
"os.osx.x86_64": true,
|
||||
"os.osx.arm64": true,
|
||||
"os.linux.x86_64": true,
|
||||
"os.windows.x86_64": true,
|
||||
};
|
||||
@@ -157,9 +158,11 @@ export function host() {
|
||||
if (platform === "darwin") {
|
||||
// Can't just test uname -m = x86_64, because Snow Leopard can
|
||||
// return other values.
|
||||
if (run('uname', '-p') !== "i386" ||
|
||||
const arch = run('uname', '-p');
|
||||
|
||||
if ((arch !== "i386" && arch !== "arm") ||
|
||||
run('sysctl', '-n', 'hw.cpu64bit_capable') !== "1") {
|
||||
throw new Error("Only 64-bit Intel processors are supported on OS X");
|
||||
throw new Error("Only 64-bit Intel and M1 processors are supported on OS X");
|
||||
}
|
||||
_host = "os.osx.x86_64";
|
||||
} else if (platform === "linux") {
|
||||
|
||||
Reference in New Issue
Block a user