From: Lisa Knox Date: Thu, 16 May 2024 13:41:37 +0000 (-0400) Subject: Merge branch '21535-multi-wf-delete' X-Git-Url: https://git.arvados.org/arvados.git/commitdiff_plain/refs/heads/main?hp=b347fbbbcc4fef0d06e0c36817f23e890f65b638 Merge branch '21535-multi-wf-delete' closes #21535 Arvados-DCO-1.1-Signed-off-by: Lisa Knox --- diff --git a/.gitignore b/.gitignore index 557386b99c..2b98a71967 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,4 @@ _version.py arvados-snakeoil-ca.pem .vagrant packages +.eslintcache diff --git a/.licenseignore b/.licenseignore index 1e1c12a53a..926aff75a4 100644 --- a/.licenseignore +++ b/.licenseignore @@ -43,6 +43,7 @@ docker/jobs/1078ECD7.key *.min.js *.png */proc_stat +*/pytest.ini */README */robots.txt */runit-docker/* diff --git a/build/README b/build/README index e6d14cf664..219b7791bf 100644 --- a/build/README +++ b/build/README @@ -80,9 +80,6 @@ In order to build packages on a new distribution, you MUST: * Add the new `TARGET/generated` rule to the `all` target in `package-build-dockerfiles/Makefile`. * Write `package-build-dockerfiles/TARGET/Dockerfile`. -* Add a rule for `TARGET/generated` to `package-test-dockerfiles/Makefile`. -* Add the new `TARGET/generated` rule to the `all` target in - `package-test-dockerfiles/Makefile`. * Write `package-test-dockerfiles/TARGET/Dockerfile`. * Create `package-testing/test-packages-TARGET.sh`, ideally by making it a symlink to `FORMAT-common-test-packages.sh`. diff --git a/build/package-build-dockerfiles/Makefile b/build/package-build-dockerfiles/Makefile index be27fffab7..920d626483 100644 --- a/build/package-build-dockerfiles/Makefile +++ b/build/package-build-dockerfiles/Makefile @@ -43,10 +43,7 @@ HOSTTYPE=$(shell echo $${HOSTTYPE}) GOTARBALL=${GOTARBALL_$(HOSTTYPE)} NODETARBALL=${NODETARBALL_$(HOSTTYPE)} -RVMKEY1=mpapis.asc -RVMKEY2=pkuczynski.asc - -common-generated-all: common-generated/$(GOTARBALL) common-generated/$(NODETARBALL) common-generated/$(RVMKEY1) common-generated/$(RVMKEY2) +common-generated-all: common-generated/$(GOTARBALL) common-generated/$(NODETARBALL) common-generated/$(GOTARBALL): common-generated wget -cqO common-generated/$(GOTARBALL) https://dl.google.com/go/$(GOTARBALL) @@ -54,11 +51,5 @@ common-generated/$(GOTARBALL): common-generated common-generated/$(NODETARBALL): common-generated wget -cqO common-generated/$(NODETARBALL) https://nodejs.org/dist/v12.22.12/$(NODETARBALL) -common-generated/$(RVMKEY1): common-generated - wget -cqO common-generated/$(RVMKEY1) https://rvm.io/mpapis.asc - -common-generated/$(RVMKEY2): common-generated - wget -cqO common-generated/$(RVMKEY2) https://rvm.io/pkuczynski.asc - common-generated: mkdir common-generated diff --git a/build/package-build-dockerfiles/debian11/Dockerfile b/build/package-build-dockerfiles/debian11/Dockerfile index 5ca7e1f243..c1c9e2d921 100644 --- a/build/package-build-dockerfiles/debian11/Dockerfile +++ b/build/package-build-dockerfiles/debian11/Dockerfile @@ -6,7 +6,6 @@ ARG HOSTTYPE ARG BRANCH ARG GOVERSION -## dont use debian:11 here since the word 'bullseye' is used for rvm precompiled binaries FROM debian:bullseye as build_x86_64 # Install go ONBUILD ARG BRANCH @@ -46,36 +45,42 @@ ENV DEBIAN_FRONTEND noninteractive SHELL ["/bin/bash", "-c"] # Install dependencies. -RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python3 libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev unzip python3-venv python3-dev libpam-dev equivs +RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y \ + build-essential \ + curl \ + equivs \ + git \ + libattr1-dev \ + libcurl4-gnutls-dev \ + libfuse-dev \ + libgnutls28-dev \ + libpam-dev \ + libpq-dev \ + pkgconf \ + procps \ + python3 \ + python3-dev \ + python3-venv \ + ruby \ + ruby-dev \ + unzip -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ # fpm depends on dotenv, but version 3.0 of that gem dropped support for # Ruby 2.7, so we need to specifically install an older version. -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 2.7 -j $(grep -c processor /proc/cpuinfo) --disable-binary && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ - echo "gem: --no-document" >> ~/.gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \ - /usr/local/rvm/bin/rvm-exec default gem install dotenv --version '~> 2.8' && \ - /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.15.1 +RUN echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '~> 2.4.0' bundler && \ + gem install dotenv --version '~> 2.8' && \ + gem install fpm --version 1.15.1 && \ + bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) -RUN /usr/local/rvm/bin/rvm-exec default bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/ ENV MAKE "make --jobs $(grep -c processor /proc/cpuinfo)" -# Preseed the go module cache and the ruby gems, using the currently checked -# out branch of the source tree. This avoids potential compatibility issues -# between the version of Ruby and certain gems. +# Preseed the go module cache. RUN git clone git://git.arvados.org/arvados.git /tmp/arvados && \ cd /tmp/arvados && \ if [[ -n "${BRANCH}" ]]; then git checkout ${BRANCH}; fi && \ - cd /tmp/arvados/services/api && \ - /usr/local/rvm/bin/rvm-exec default bundle install && \ - cd /tmp/arvados && \ go mod download ENV WORKSPACE /arvados -CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "debian11"] +CMD ["bash", "/jenkins/run-build-packages.sh", "--target", "debian11"] diff --git a/build/package-build-dockerfiles/debian12/Dockerfile b/build/package-build-dockerfiles/debian12/Dockerfile index fa1d095e79..e25745565e 100644 --- a/build/package-build-dockerfiles/debian12/Dockerfile +++ b/build/package-build-dockerfiles/debian12/Dockerfile @@ -6,7 +6,6 @@ ARG HOSTTYPE ARG BRANCH ARG GOVERSION -## dont use debian:12 here since the word 'bookworm' is used for rvm precompiled binaries FROM debian:bookworm as build_x86_64 ONBUILD ARG BRANCH # Install go @@ -44,34 +43,39 @@ ENV DEBIAN_FRONTEND noninteractive SHELL ["/bin/bash", "-c"] # Install dependencies. -RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python3 libcurl4-gnutls-dev curl git procps libattr1-dev libfuse-dev libgnutls28-dev libpq-dev unzip python3-venv python3-dev libpam-dev equivs +RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y \ + build-essential \ + curl \ + equivs \ + git \ + libattr1-dev \ + libcurl4-gnutls-dev \ + libfuse-dev \ + libgnutls28-dev \ + libpam-dev \ + libpq-dev \ + pkgconf \ + procps \ + python3 \ + python3-dev \ + python3-venv \ + ruby \ + ruby-dev \ + unzip -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 3.2.2 -j $(grep -c processor /proc/cpuinfo) --disable-binary && \ - /usr/local/rvm/bin/rvm alias create default ruby-3.2.2 && \ - echo "gem: --no-document" >> ~/.gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \ - /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.15.1 +RUN echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '>= 2.4.0' bundler && \ + gem install fpm --version 1.15.1 && \ + bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) -RUN /usr/local/rvm/bin/rvm-exec default bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/ ENV MAKE "make --jobs 8" -# Preseed the go module cache and the ruby gems, using the currently checked -# out branch of the source tree. This avoids potential compatibility issues -# between the version of Ruby and certain gems. +# Preseed the go module cache. RUN git clone git://git.arvados.org/arvados.git /tmp/arvados && \ cd /tmp/arvados && \ if [[ -n "${BRANCH}" ]]; then git checkout ${BRANCH}; fi && \ - cd /tmp/arvados/services/api && \ - /usr/local/rvm/bin/rvm-exec default bundle install && \ - cd /tmp/arvados && \ go mod download ENV WORKSPACE /arvados -CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "debian12"] +CMD ["bash", "/jenkins/run-build-packages.sh", "--target", "debian12"] diff --git a/build/package-build-dockerfiles/rocky8/Dockerfile b/build/package-build-dockerfiles/rocky8/Dockerfile index a1038a9b88..1292a618bc 100644 --- a/build/package-build-dockerfiles/rocky8/Dockerfile +++ b/build/package-build-dockerfiles/rocky8/Dockerfile @@ -35,7 +35,8 @@ FROM build_${HOSTTYPE} MAINTAINER Arvados Package Maintainers # Install dependencies. -RUN microdnf --assumeyes --enablerepo=devel install \ +RUN microdnf --assumeyes module enable ruby:3.1 \ + && microdnf --assumeyes --enablerepo=devel install \ automake \ bison \ bzip2 \ @@ -53,6 +54,7 @@ RUN microdnf --assumeyes --enablerepo=devel install \ openssl-devel \ pam-devel \ patch \ + pkgconf \ postgresql-devel \ procps-ng \ python39 \ @@ -60,6 +62,7 @@ RUN microdnf --assumeyes --enablerepo=devel install \ readline-devel \ rpm-build \ ruby \ + ruby-devel \ sqlite-devel \ tar \ unzip \ @@ -68,34 +71,22 @@ RUN microdnf --assumeyes --enablerepo=devel install \ xz-libs \ zlib-devel -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ # fpm depends on dotenv, but version 3.0 of that gem dropped support for # Ruby 2.7, so we need to specifically install an older version. -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install --disable-binary 2.7 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ - echo "gem: --no-document" >> ~/.gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \ - /usr/local/rvm/bin/rvm-exec default gem install dotenv --version '~> 2.8' && \ - /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.15.1 +RUN echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '>= 2.4.0' bundler && \ + gem install dotenv --version '~> 2.8' && \ + gem install fpm --version 1.15.1 && \ + bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) -RUN /usr/local/rvm/bin/rvm-exec default bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/ ENV MAKE "make --jobs $(grep -c processor /proc/cpuinfo)" -# Preseed the go module cache and the ruby gems, using the currently checked -# out branch of the source tree. This avoids potential compatibility issues -# between the version of Ruby and certain gems. +# Preseed the go module cache. RUN git clone git://git.arvados.org/arvados.git /tmp/arvados && \ cd /tmp/arvados && \ if [[ -n "${BRANCH}" ]]; then git checkout ${BRANCH}; fi && \ - cd /tmp/arvados/services/api && \ - /usr/local/rvm/bin/rvm-exec default bundle install && \ - cd /tmp/arvados && \ go mod download ENV WORKSPACE /arvados -CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "rocky8"] +CMD ["bash", "/jenkins/run-build-packages.sh", "--target", "rocky8"] diff --git a/build/package-build-dockerfiles/ubuntu2004/Dockerfile b/build/package-build-dockerfiles/ubuntu2004/Dockerfile index 576b6021c0..dc57c8c03f 100644 --- a/build/package-build-dockerfiles/ubuntu2004/Dockerfile +++ b/build/package-build-dockerfiles/ubuntu2004/Dockerfile @@ -50,36 +50,43 @@ ENV DEBIAN_FRONTEND noninteractive SHELL ["/bin/bash", "-c"] # Install dependencies. -RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python3 libcurl4-gnutls-dev libgnutls28-dev curl git libattr1-dev libfuse-dev libpq-dev unzip tzdata python3-venv python3-dev libpam-dev shared-mime-info equivs +RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y \ + build-essential \ + curl \ + equivs \ + git \ + libattr1-dev \ + libcurl4-gnutls-dev \ + libfuse-dev \ + libgnutls28-dev \ + libpam-dev \ + libpq-dev \ + pkgconf \ + python3 \ + python3-dev \ + python3-venv \ + ruby \ + ruby-dev \ + shared-mime-info \ + tzdata \ + unzip -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ # fpm depends on dotenv, but version 3.0 of that gem dropped support for # Ruby 2.7, so we need to specifically install an older version. -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 2.7 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ - echo "gem: --no-document" >> ~/.gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \ - /usr/local/rvm/bin/rvm-exec default gem install dotenv --version '~> 2.8' && \ - /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.15.1 +RUN echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '~> 2.4.0' bundler && \ + gem install dotenv --version '~> 2.8' && \ + gem install fpm --version 1.15.1 && \ + bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) -RUN /usr/local/rvm/bin/rvm-exec default bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/ ENV MAKE "make --jobs $(grep -c processor /proc/cpuinfo)" -# Preseed the go module cache and the ruby gems, using the currently checked -# out branch of the source tree. This avoids potential compatibility issues -# between the version of Ruby and certain gems. +# Preseed the go module cache. RUN git clone git://git.arvados.org/arvados.git /tmp/arvados && \ cd /tmp/arvados && \ if [[ -n "${BRANCH}" ]]; then git checkout ${BRANCH}; fi && \ - cd /tmp/arvados/services/api && \ - /usr/local/rvm/bin/rvm-exec default bundle install && \ - cd /tmp/arvados && \ go mod download ENV WORKSPACE /arvados -CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu2004"] +CMD ["bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu2004"] diff --git a/build/package-build-dockerfiles/ubuntu2204/Dockerfile b/build/package-build-dockerfiles/ubuntu2204/Dockerfile index 79664fea6b..35ef93ff2d 100644 --- a/build/package-build-dockerfiles/ubuntu2204/Dockerfile +++ b/build/package-build-dockerfiles/ubuntu2204/Dockerfile @@ -44,35 +44,40 @@ ENV DEBIAN_FRONTEND noninteractive SHELL ["/bin/bash", "-c"] # Install dependencies. -RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y python3 libcurl4-gnutls-dev libgnutls28-dev curl git libattr1-dev libfuse-dev libpq-dev unzip tzdata python3-venv python3-dev libpam-dev shared-mime-info equivs +RUN /usr/bin/apt-get update && /usr/bin/apt-get install -q -y \ + build-essential \ + curl \ + equivs \ + git \ + libattr1-dev \ + libcurl4-gnutls-dev \ + libfuse-dev \ + libgnutls28-dev \ + libpam-dev \ + libpq-dev \ + pkgconf \ + python3 \ + python3-dev \ + python3-venv \ + ruby \ + ruby-dev \ + shared-mime-info \ + tzdata \ + unzip -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 3.2.2 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-3.2.2 && \ - echo "gem: --no-document" >> ~/.gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 && \ - /usr/local/rvm/bin/rvm-exec default gem install fpm --version 1.15.1 +RUN echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '>= 2.4.0' bundler && \ + gem install fpm --version 1.15.1 && \ + bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) -RUN /usr/local/rvm/bin/rvm-exec default bundle config --global jobs $(let a=$(grep -c processor /proc/cpuinfo )-1; echo $a) # Cf. https://build.betterup.com/one-weird-trick-that-will-speed-up-your-bundle-install/ ENV MAKE "make --jobs 8" -# Preseed the go module cache and the ruby gems, using the currently checked -# out branch of the source tree. This avoids potential compatibility issues -# between the version of Ruby and certain gems. +# Preseed the go module cache. RUN git clone git://git.arvados.org/arvados.git /tmp/arvados && \ cd /tmp/arvados && \ if [[ -n "${BRANCH}" ]]; then git checkout ${BRANCH}; fi && \ - cd /tmp/arvados/services/api && \ - /usr/local/rvm/bin/rvm-exec default bundle install && \ - cd /tmp/arvados && \ go mod download - ENV WORKSPACE /arvados -CMD ["/usr/local/rvm/bin/rvm-exec", "default", "bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu2204"] +CMD ["bash", "/jenkins/run-build-packages.sh", "--target", "ubuntu2204"] diff --git a/build/package-test-dockerfiles/.gitignore b/build/package-test-dockerfiles/.gitignore index ceee9faa15..01d69cb3de 100644 --- a/build/package-test-dockerfiles/.gitignore +++ b/build/package-test-dockerfiles/.gitignore @@ -1,2 +1 @@ */generated -common-generated/ diff --git a/build/package-test-dockerfiles/Makefile b/build/package-test-dockerfiles/Makefile deleted file mode 100644 index 02e2846a2a..0000000000 --- a/build/package-test-dockerfiles/Makefile +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -all: debian11/generated -debian11/generated: common-generated-all - test -d debian11/generated || mkdir debian11/generated - cp -f -rlt debian11/generated common-generated/* - -all: debian12/generated -debian12/generated: common-generated-all - test -d debian12/generated || mkdir debian12/generated - cp -f -rlt debian12/generated common-generated/* - -all: rocky8/generated -rocky8/generated: common-generated-all - test -d rocky8/generated || mkdir rocky8/generated - cp -f -rlt rocky8/generated common-generated/* - -all: ubuntu2004/generated -ubuntu2004/generated: common-generated-all - test -d ubuntu2004/generated || mkdir ubuntu2004/generated - cp -f -rlt ubuntu2004/generated common-generated/* - -all: ubuntu2204/generated -ubuntu2204/generated: common-generated-all - test -d ubuntu2204/generated || mkdir ubuntu2204/generated - cp -f -rlt ubuntu2204/generated common-generated/* - -RVMKEY1=mpapis.asc -RVMKEY2=pkuczynski.asc - -common-generated-all: common-generated/$(RVMKEY1) common-generated/$(RVMKEY2) - -common-generated/$(RVMKEY1): common-generated - wget -cqO common-generated/$(RVMKEY1) https://rvm.io/mpapis.asc - -common-generated/$(RVMKEY2): common-generated - wget -cqO common-generated/$(RVMKEY2) https://rvm.io/pkuczynski.asc - -common-generated: - mkdir common-generated diff --git a/build/package-test-dockerfiles/debian11/Dockerfile b/build/package-test-dockerfiles/debian11/Dockerfile index a659e105d1..cd57ffde62 100644 --- a/build/package-test-dockerfiles/debian11/Dockerfile +++ b/build/package-test-dockerfiles/debian11/Dockerfile @@ -9,20 +9,8 @@ ENV DEBIAN_FRONTEND noninteractive # Install dependencies RUN apt-get update && \ - apt-get -y install --no-install-recommends curl ca-certificates gpg procps gpg-agent - -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 2.7 -j $(grep -c processor /proc/cpuinfo) --disable-binary && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ + apt-get -y install --no-install-recommends curl ca-certificates gpg procps gpg-agent ruby ruby-dev && \ echo "gem: --no-document" >> /etc/gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 - -# udev daemon can't start in a container, so don't try. -RUN mkdir -p /etc/udev/disabled - -RUN echo "deb file:///arvados/packages/debian11/ /" >>/etc/apt/sources.list + gem install --conservative --version '~> 2.4.0' bundler && \ + mkdir -p /etc/udev/disabled && \ + echo "deb file:///arvados/packages/debian11/ /" >>/etc/apt/sources.list diff --git a/build/package-test-dockerfiles/debian12/Dockerfile b/build/package-test-dockerfiles/debian12/Dockerfile index 4cdc41d73b..6cc700d742 100644 --- a/build/package-test-dockerfiles/debian12/Dockerfile +++ b/build/package-test-dockerfiles/debian12/Dockerfile @@ -9,20 +9,8 @@ ENV DEBIAN_FRONTEND noninteractive # Install dependencies RUN apt-get update && \ - apt-get -y install --no-install-recommends curl ca-certificates gpg procps gpg-agent - -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 3.2.2 -j $(grep -c processor /proc/cpuinfo) --disable-binary && \ - /usr/local/rvm/bin/rvm alias create default ruby-3.2.2 && \ + apt-get -y install --no-install-recommends curl ca-certificates gpg procps gpg-agent ruby ruby-dev && \ echo "gem: --no-document" >> /etc/gemrc && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 - -# udev daemon can't start in a container, so don't try. -RUN mkdir -p /etc/udev/disabled - -RUN echo "deb file:///arvados/packages/debian12/ /" >>/etc/apt/sources.list + gem install --conservative --version '>= 2.4.0' bundler && \ + mkdir -p /etc/udev/disabled && \ + echo "deb file:///arvados/packages/debian12/ /" >>/etc/apt/sources.list diff --git a/build/package-test-dockerfiles/rocky8/Dockerfile b/build/package-test-dockerfiles/rocky8/Dockerfile index 809f3626ca..b58791ee91 100644 --- a/build/package-test-dockerfiles/rocky8/Dockerfile +++ b/build/package-test-dockerfiles/rocky8/Dockerfile @@ -2,11 +2,12 @@ # # SPDX-License-Identifier: AGPL-3.0 -FROM rockylinux:8.6-minimal +FROM rockylinux:8.8-minimal MAINTAINER Arvados Package Maintainers # Install dependencies. -RUN microdnf --assumeyes --enablerepo=devel install \ +RUN microdnf --assumeyes module enable httpd:2.4 postgresql:10 python39:3.9 ruby:3.1 \ + && microdnf --assumeyes --enablerepo=devel install \ autoconf \ automake \ bison \ @@ -23,10 +24,13 @@ RUN microdnf --assumeyes --enablerepo=devel install \ make \ openssl-devel \ patch \ + pkgconf \ procps-ng \ - python3 \ + python39 \ readline-devel \ + redhat-rpm-config \ ruby \ + ruby-devel \ shadow-utils \ sqlite-devel \ tar \ @@ -34,15 +38,8 @@ RUN microdnf --assumeyes --enablerepo=devel install \ which \ zlib-devel -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ RUN touch /var/lib/rpm/* && \ - gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install --disable-binary 2.7 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 + echo "gem: --no-document" >> ~/.gemrc && \ + gem install --conservative --version '>= 2.4.0' bundler COPY localrepo.repo /etc/yum.repos.d/localrepo.repo diff --git a/build/package-test-dockerfiles/ubuntu2004/Dockerfile b/build/package-test-dockerfiles/ubuntu2004/Dockerfile index df1e71e75a..c996a8b972 100644 --- a/build/package-test-dockerfiles/ubuntu2004/Dockerfile +++ b/build/package-test-dockerfiles/ubuntu2004/Dockerfile @@ -9,19 +9,7 @@ ENV DEBIAN_FRONTEND noninteractive # Install dependencies RUN apt-get update && \ - apt-get -y install --no-install-recommends curl ca-certificates gnupg2 - -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 2.7 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-2.7 && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 - -# udev daemon can't start in a container, so don't try. -RUN mkdir -p /etc/udev/disabled - -RUN echo "deb [trusted=yes] file:///arvados/packages/ubuntu2004/ /" >>/etc/apt/sources.list + apt-get -y install --no-install-recommends curl ca-certificates gnupg2 ruby ruby-dev && \ + gem install --conservative --version '~> 2.4.0' bundler && \ + mkdir -p /etc/udev/disabled && \ + echo "deb [trusted=yes] file:///arvados/packages/ubuntu2004/ /" >>/etc/apt/sources.list diff --git a/build/package-test-dockerfiles/ubuntu2204/Dockerfile b/build/package-test-dockerfiles/ubuntu2204/Dockerfile index 4926a6573f..01a0496284 100644 --- a/build/package-test-dockerfiles/ubuntu2204/Dockerfile +++ b/build/package-test-dockerfiles/ubuntu2204/Dockerfile @@ -9,19 +9,7 @@ ENV DEBIAN_FRONTEND noninteractive # Install dependencies RUN apt-get update && \ - apt-get -y install --no-install-recommends curl ca-certificates gnupg2 - -# Install RVM -ADD generated/mpapis.asc /tmp/ -ADD generated/pkuczynski.asc /tmp/ -RUN gpg --import --no-tty /tmp/mpapis.asc && \ - gpg --import --no-tty /tmp/pkuczynski.asc && \ - curl -L https://get.rvm.io | bash -s stable && \ - /usr/local/rvm/bin/rvm install 3.2.2 -j $(grep -c processor /proc/cpuinfo) && \ - /usr/local/rvm/bin/rvm alias create default ruby-3.2.2 && \ - /usr/local/rvm/bin/rvm-exec default gem install bundler --version 2.2.19 - -# udev daemon can't start in a container, so don't try. -RUN mkdir -p /etc/udev/disabled - -RUN echo "deb [trusted=yes] file:///arvados/packages/ubuntu2204/ /" >>/etc/apt/sources.list + apt-get -y install --no-install-recommends curl ca-certificates gnupg2 ruby ruby-dev && \ + gem install --conservative --version '>= 2.4.0' bundler && \ + mkdir -p /etc/udev/disabled && \ + echo "deb [trusted=yes] file:///arvados/packages/ubuntu2204/ /" >>/etc/apt/sources.list diff --git a/build/package-testing/common-test-rails-server-package.sh b/build/package-testing/common-test-rails-server-package.sh index ee855d8012..62b30c37d1 100755 --- a/build/package-testing/common-test-rails-server-package.sh +++ b/build/package-testing/common-test-rails-server-package.sh @@ -29,4 +29,4 @@ case "$TARGET" in ;; esac -/usr/local/rvm/bin/rvm-exec default bundle list >"$ARV_PACKAGES_DIR/$PACKAGE_NAME.gems" +bundle list >"$ARV_PACKAGES_DIR/$PACKAGE_NAME.gems" diff --git a/build/package-testing/rpm-common-test-packages.sh b/build/package-testing/rpm-common-test-packages.sh index cd41f1d920..b6d7fec468 100755 --- a/build/package-testing/rpm-common-test-packages.sh +++ b/build/package-testing/rpm-common-test-packages.sh @@ -30,6 +30,10 @@ diff "$ARV_PACKAGES_DIR/$1".{before,after} >"$ARV_PACKAGES_DIR/$1.diff" || true mkdir -p /tmp/opts cd /tmp/opts +# Install other packages alongside to test for build id conflicts. +# This line can be removed after we have test-provision-rocky8, #21426. +microdnf --assumeyes install arvados-client arvados-server python3-arvados-python-client + rpm2cpio $(ls -t "$ARV_PACKAGES_DIR/$1"-*.rpm | head -n1) | cpio -idm 2>/dev/null if [[ "$DEBUG" != "0" ]]; then diff --git a/build/rails-package-scripts/README.md b/build/rails-package-scripts/README.md index 6ac2539f8e..08772ce02f 100644 --- a/build/rails-package-scripts/README.md +++ b/build/rails-package-scripts/README.md @@ -13,5 +13,4 @@ Since our build process is a tower of shell scripts, concatenating files seemed postinst.sh lets the early parts define a few hooks to control behavior: * After it installs the core configuration files (database.yml, application.yml, and production.rb) to /etc/arvados/server, it calls setup_extra_conffiles. By default this is a noop function (in step2.sh). -* Before it restarts nginx, it calls setup_before_nginx_restart. By default this is a noop function (in step2.sh). API server defines this to set up the internal git repository, if necessary. * $RAILSPKG_DATABASE_LOAD_TASK defines the Rake task to load the database. API server uses db:structure:load. Workbench doesn't set this, which causes the postinst to skip all database work. diff --git a/build/rails-package-scripts/arvados-api-server.sh b/build/rails-package-scripts/arvados-api-server.sh index a0e356ce32..493147d521 100644 --- a/build/rails-package-scripts/arvados-api-server.sh +++ b/build/rails-package-scripts/arvados-api-server.sh @@ -16,23 +16,3 @@ setup_extra_conffiles() { # can still be there, left over from a previous version of the API server package. rm -f $RELEASE_PATH/config/initializers/omniauth.rb } - -setup_before_nginx_restart() { - # initialize git_internal_dir - # usually /var/lib/arvados/internal.git (set in application.default.yml ) - if [ "$APPLICATION_READY" = "1" ]; then - GIT_INTERNAL_DIR=$($COMMAND_PREFIX bin/rake config:dump 2>&1 | grep GitInternalDir | awk '{ print $2 }' |tr -d '"') - if [ ! -e "$GIT_INTERNAL_DIR" ]; then - run_and_report "Creating git_internal_dir '$GIT_INTERNAL_DIR'" \ - mkdir -p "$GIT_INTERNAL_DIR" - run_and_report "Initializing git_internal_dir '$GIT_INTERNAL_DIR'" \ - git init --quiet --bare $GIT_INTERNAL_DIR - else - echo "Initializing git_internal_dir $GIT_INTERNAL_DIR: directory exists, skipped." - fi - run_and_report "Making sure '$GIT_INTERNAL_DIR' has the right permission" \ - chown -R "$WWW_OWNER:" "$GIT_INTERNAL_DIR" - else - echo "Initializing git_internal_dir... skipped." - fi -} diff --git a/build/rails-package-scripts/postinst.sh b/build/rails-package-scripts/postinst.sh index e317f85aaf..b5f78f988c 100644 --- a/build/rails-package-scripts/postinst.sh +++ b/build/rails-package-scripts/postinst.sh @@ -10,12 +10,6 @@ set -e DATABASE_READY=1 APPLICATION_READY=1 -if [ -s "$HOME/.rvm/scripts/rvm" ] || [ -s "/usr/local/rvm/scripts/rvm" ]; then - COMMAND_PREFIX="/usr/local/rvm/bin/rvm-exec default" -else - COMMAND_PREFIX= -fi - report_not_ready() { local ready_flag="$1"; shift local config_file="$1"; shift @@ -125,17 +119,17 @@ setup_conffile() { } prepare_database() { - DB_MIGRATE_STATUS=`$COMMAND_PREFIX bin/rake db:migrate:status 2>&1 || true` + DB_MIGRATE_STATUS=`bin/rake db:migrate:status 2>&1 || true` if echo "$DB_MIGRATE_STATUS" | grep -qF 'Schema migrations table does not exist yet.'; then # The database exists, but the migrations table doesn't. - run_and_report "Setting up database" $COMMAND_PREFIX bin/rake \ + run_and_report "Setting up database" bin/rake \ "$RAILSPKG_DATABASE_LOAD_TASK" db:seed elif echo "$DB_MIGRATE_STATUS" | grep -q '^database: '; then run_and_report "Running db:migrate" \ - $COMMAND_PREFIX bin/rake db:migrate + bin/rake db:migrate elif echo "$DB_MIGRATE_STATUS" | grep -q 'database .* does not exist'; then if ! run_and_report "Running db:setup" \ - $COMMAND_PREFIX bin/rake db:setup 2>/dev/null; then + bin/rake db:setup 2>/dev/null; then echo "Warning: unable to set up database." >&2 DATABASE_READY=0 fi @@ -198,15 +192,26 @@ configure_version() { cd "$RELEASE_PATH" export RAILS_ENV=production - if ! $COMMAND_PREFIX bundle --version >/dev/null 2>&1; then - run_and_report "Installing bundler" $COMMAND_PREFIX gem install bundler --version 2.2.19 --no-document + run_and_report "Installing bundler" gem install --conservative --version '~> 2.4.0' bundler + local bundle="$(gem contents --version '~> 2.4.0' bundler | grep '/exe/bundle$' | tail -n1)" + if ! [ -x "$bundle" ]; then + echo "Error: failed to find \`bundle\` command after installing bundler gem" >&2 + return 1 fi + local bundle_path="$SHARED_PATH/vendor_bundle" run_and_report "Running bundle config set --local path $SHARED_PATH/vendor_bundle" \ - $COMMAND_PREFIX bin/bundle config set --local path $SHARED_PATH/vendor_bundle - - run_and_report "Running bundle install" \ - $COMMAND_PREFIX bin/bundle install --local --quiet + "$bundle" config set --local path "$bundle_path" + + # As of April 2024/Bundler 2.4, `bundle install` tends not to install gems + # which are already installed system-wide, which causes bundle activation to + # fail later. Work around this by installing all gems manually. + find vendor/cache -maxdepth 1 -name '*.gem' -print0 \ + | run_and_report "Installing bundle gems" xargs -0r \ + gem install --conservative --ignore-dependencies --local --quiet \ + --install-dir="$bundle_path/ruby/$(ruby -e 'puts RUBY_VERSION')" + run_and_report "Running bundle install" "$bundle" install --prefer-local --quiet + run_and_report "Verifying bundle is complete" "$bundle" exec true echo -n "Ensuring directory and file permissions ..." # Ensure correct ownership of a few files @@ -236,15 +241,13 @@ configure_version() { # warn about config errors (deprecated/removed keys from # previous version, etc) run_and_report "Checking configuration for completeness" \ - $COMMAND_PREFIX bin/rake config:check || APPLICATION_READY=0 + bin/rake config:check || APPLICATION_READY=0 else APPLICATION_READY=0 fi chown -R "$WWW_OWNER:" $RELEASE_PATH/tmp - setup_before_nginx_restart - if [ -n "$SERVICE_MANAGER" ]; then service_command "$SERVICE_MANAGER" restart "$WEB_SERVICE" fi diff --git a/build/rails-package-scripts/step2.sh b/build/rails-package-scripts/step2.sh index 41c9cd71e3..4af0e4a01b 100644 --- a/build/rails-package-scripts/step2.sh +++ b/build/rails-package-scripts/step2.sh @@ -26,9 +26,6 @@ SHARED_PATH=$INSTALL_PATH/shared if ! type setup_extra_conffiles >/dev/null 2>&1; then setup_extra_conffiles() { return; } fi -if ! type setup_before_nginx_restart >/dev/null 2>&1; then - setup_before_nginx_restart() { return; } -fi if [ -e /run/systemd/system ]; then USING_SYSTEMD=1 diff --git a/build/run-build-packages-one-target.sh b/build/run-build-packages-one-target.sh index 37fe705241..b1801dd307 100755 --- a/build/run-build-packages-one-target.sh +++ b/build/run-build-packages-one-target.sh @@ -198,7 +198,7 @@ if [[ -n "$test_packages" ]]; then else IMAGE="arvados/build:$TARGET" if [[ "$COMMAND" != "" ]]; then - COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET$DEBUG" + COMMAND="bash /jenkins/$COMMAND --target $TARGET$DEBUG" fi fi @@ -206,11 +206,10 @@ JENKINS_DIR=$(dirname "$(readlink -e "$0")") if [[ "$SKIP_DOCKER_BUILD" != 1 ]] ; then if [[ -n "$test_packages" ]]; then - pushd "$JENKINS_DIR/package-test-dockerfiles" - make "$TARGET/generated" + pushd "$JENKINS_DIR/package-test-dockerfiles" else - pushd "$JENKINS_DIR/package-build-dockerfiles" - make "$TARGET/generated" + pushd "$JENKINS_DIR/package-build-dockerfiles" + make "$TARGET/generated" fi GOVERSION=$(grep 'const goversion =' $WORKSPACE/lib/install/deps.go |awk -F'"' '{print $2}') @@ -231,7 +230,6 @@ if test -z "$packages" ; then arvados-dispatch-cloud arvados-dispatch-lsf arvados-docker-cleaner - arvados-git-httpd arvados-health arvados-server arvados-src @@ -267,7 +265,8 @@ mkdir -p "$WORKSPACE/services/api/vendor/cache-$TARGET" docker_volume_args=( -v "$JENKINS_DIR:/jenkins" -v "$WORKSPACE:/arvados" - -v /arvados/services/api/vendor/bundle + --tmpfs /arvados/services/api/.bundle:rw,noexec,nosuid,size=1m + --tmpfs /arvados/services/api/vendor:rw,exec,nosuid,size=1g -v "$WORKSPACE/services/api/vendor/cache-$TARGET:/arvados/services/api/vendor/cache" ) diff --git a/build/run-build-packages-python-and-ruby.sh b/build/run-build-packages-python-and-ruby.sh index 599fe7cf96..285bb11d71 100755 --- a/build/run-build-packages-python-and-ruby.sh +++ b/build/run-build-packages-python-and-ruby.sh @@ -165,13 +165,6 @@ if [ $RUBY -eq 0 ] && [ $PYTHON -eq 0 ]; then exit 0 fi -if [[ -f /etc/profile.d/rvm.sh ]]; then - source /etc/profile.d/rvm.sh - GEM="rvm-exec default gem" -else - GEM=gem -fi - # Make all files world-readable -- jenkins runs with umask 027, and has checked # out our git tree here chmod o+r "$WORKSPACE" -R diff --git a/build/run-build-packages.sh b/build/run-build-packages.sh index ada3bf8b6c..588ebedb92 100755 --- a/build/run-build-packages.sh +++ b/build/run-build-packages.sh @@ -102,7 +102,7 @@ elif [[ ! -d "$WORKSPACE/build/package-build-dockerfiles/$TARGET" ]]; then fi if [[ "$COMMAND" != "" ]]; then - COMMAND="/usr/local/rvm/bin/rvm-exec default bash /jenkins/$COMMAND --target $TARGET" + COMMAND="bash /jenkins/$COMMAND --target $TARGET" fi STDOUT_IF_DEBUG=/dev/null @@ -181,13 +181,6 @@ fi debug_echo "$0 is running from $RUN_BUILD_PACKAGES_PATH" debug_echo "Workspace is $WORKSPACE" -if [[ -f /etc/profile.d/rvm.sh ]]; then - source /etc/profile.d/rvm.sh - GEM="rvm-exec default gem" -else - GEM=gem -fi - # Make all files world-readable -- jenkins runs with umask 027, and has checked # out our git tree here chmod o+r "$WORKSPACE" -R @@ -213,7 +206,7 @@ git config --global --add safe.directory /arvados # Ruby gems debug_echo -e "\nRuby gems\n" -FPM_GEM_PREFIX=$($GEM environment gemdir) +FPM_GEM_PREFIX=$(gem environment gemdir) cd "$WORKSPACE/sdk/ruby" || exit 1 handle_ruby_gem arvados @@ -242,8 +235,6 @@ package_go_binary cmd/arvados-server arvados-dispatch-cloud "$FORMAT" "$ARCH" \ "Arvados cluster cloud dispatch" package_go_binary cmd/arvados-server arvados-dispatch-lsf "$FORMAT" "$ARCH" \ "Dispatch Arvados containers to an LSF cluster" -package_go_binary cmd/arvados-server arvados-git-httpd "$FORMAT" "$ARCH" \ - "Provide authenticated http access to Arvados-hosted git repositories" package_go_binary services/crunch-dispatch-local crunch-dispatch-local "$FORMAT" "$ARCH" \ "Dispatch Crunch containers on the local system" package_go_binary cmd/arvados-server crunch-dispatch-slurm "$FORMAT" "$ARCH" \ diff --git a/build/run-library.sh b/build/run-library.sh index 6380e1cb19..6fdc4aafcd 100755 --- a/build/run-library.sh +++ b/build/run-library.sh @@ -111,7 +111,7 @@ handle_ruby_gem() { find -maxdepth 1 -name "${gem_name}-*.gem" -delete # -q appears to be broken in gem version 2.2.2 - $GEM build "$gem_name.gemspec" $DASHQ_UNLESS_DEBUG >"$STDOUT_IF_DEBUG" 2>"$STDERR_IF_DEBUG" + gem build "$gem_name.gemspec" $DASHQ_UNLESS_DEBUG >"$STDOUT_IF_DEBUG" 2>"$STDERR_IF_DEBUG" fi } @@ -121,6 +121,9 @@ package_workbench2() { local src=services/workbench2 local dst=/var/www/arvados-workbench2/workbench2 local description="Arvados Workbench 2" + if [[ -n "$ONLY_BUILD" ]] && [[ "$pkgname" != "$ONLY_BUILD" ]] ; then + return 0 + fi cd "$WORKSPACE/$src" local version="$(version_from_git)" rm -rf ./build @@ -262,6 +265,13 @@ package_go_binary_worker() { binpath="$GOPATH/bin/linux_${target_arch}/${basename}" fi + case "$package_format" in + # As of April 2024 we package identical Go binaries under different + # packages and names. This upsets the build id database, so don't + # register ourselves there. + rpm) switches+=(--rpm-rpmbuild-define="_build_id_links none") ;; + esac + systemd_unit="$WORKSPACE/${src_path}/${prog}.service" if [[ -e "${systemd_unit}" ]]; then switches+=( @@ -506,8 +516,38 @@ handle_rails_package() { cd "$srcdir" mkdir -p tmp git rev-parse HEAD >git-commit.version + # Please make sure you read `bundle help config` carefully before you + # modify any of these settings. Some of their names are not intuitive. + # + # `bundle cache` caches from Git and paths, not just rubygems.org. bundle config set cache_all true - bundle package + # Disallow changes to Gemfile. + bundle config set deployment true + # Avoid loading system-wide gems (although this seems to not work 100%). + bundle config set disable_shared_gems true + # `bundle cache` only downloads gems, doesn't install them. + # Our Rails postinst script does the install step. + bundle config set no_install true + # As of April 2024/Bundler 2.4, `bundle cache` seems to skip downloading + # gems that are already available system-wide... and then it complains + # that your bundle is incomplete. Work around this by fetching gems + # manually. + # TODO: Once all our supported distros have Ruby 3+, we can modify + # the awk script to print "NAME:VERSION" output, and pipe that directly + # to `xargs -0r gem fetch` for reduced overhead. + mkdir -p vendor/cache + awk -- ' +BEGIN { OFS="\0"; ORS="\0"; } +(/^[A-Z ]*$/) { level1=$0; } +(/^ [[:alpha:]]+:$/) { level2=substr($0, 3, length($0) - 3); next; } +(/^ {0,3}[[:alpha:]]/) { level2=""; next; } +(level1 == "GEM" && level2 == "specs" && NF == 2 && $1 ~ /^[[:alpha:]][-_[:alnum:]]*$/ && $2 ~ /\([[:digit:]]+[-_+.[:alnum:]]*\)$/) { + print "--version", substr($2, 2, length($2) - 2), $1; +} +' Gemfile.lock | env -C vendor/cache xargs -0r --max-args=3 gem fetch + # Despite the bug, we still run `bundle cache` to make sure Bundler is + # happy for later steps. + bundle cache ) if [[ 0 != "$?" ]] || ! cd "$WORKSPACE/packages/$TARGET"; then echo "ERROR: $pkgname package prep failed" >&2 diff --git a/build/run-tests.sh b/build/run-tests.sh index b8d2081e6e..0eb421454e 100755 --- a/build/run-tests.sh +++ b/build/run-tests.sh @@ -21,7 +21,8 @@ Options: --skip install Do not run any install steps. Just run tests. You should provide GOPATH, GEMHOME, and VENVDIR options from a previous invocation if you use this option. ---only FOO Do not test anything except the FOO component. +--only FOO Do not test anything except the FOO component. If given + more than once, all specified test suites are run. --temp DIR Install components and dependencies under DIR instead of making a new temporary directory. Implies --leave-temp. --leave-temp Do not remove GOPATH, virtualenv, and other temp dirs at exit. @@ -29,16 +30,17 @@ Options: subsequent invocations. --repeat N Repeat each install/test step until it succeeds N times. --retry Prompt to retry if an install or test suite fails. ---only-install Run specific install step +--only-install Run specific install step. If given more than once, + all but the last are ignored. --short Skip (or scale down) some slow tests. --interactive Set up, then prompt for test/install steps to perform. WORKSPACE=path Arvados source tree to test. CONFIGSRC=path Dir with config.yml file containing PostgreSQL section for use by tests. services/api_test="TEST=test/functional/arvados/v1/collections_controller_test.rb" Restrict apiserver tests to the given file -sdk/python_test="--test-suite tests.test_keep_locator" +sdk/python_test="tests/test_api.py::ArvadosApiTest" Restrict Python SDK tests to the given class -services/githttpd_test="-check.vv" +lib/dispatchcloud_test="-check.vv" Show all log messages, even when tests pass (also works with services/keepstore_test etc.) ARVADOS_DEBUG=1 @@ -85,7 +87,6 @@ lib/mount lib/pam lib/service services/api -services/githttpd services/dockercleaner services/fuse services/fuse:py3 @@ -192,7 +193,7 @@ sanity_checks() { || fatal "Locale '${LANG}' is broken/missing. Try: echo ${LANG} | sudo tee -a /etc/locale.gen && sudo locale-gen" echo -n 'ruby: ' ruby -v \ - || fatal "No ruby. Install >=2.1.9 (using rbenv, rvm, or source)" + || fatal "No ruby. Install >=2.7 from package or source" echo -n 'go: ' go version \ || fatal "No go binary. See http://golang.org/doc/install" @@ -219,9 +220,6 @@ sanity_checks() { echo -n 'nginx: ' PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" nginx -v \ || fatal "No nginx. Try: apt-get install nginx" - echo -n 'gitolite: ' - which gitolite \ - || fatal "No gitolite. Try: apt-get install gitolite3" echo -n 'npm: ' npm --version \ || fatal "No npm. Try: wget -O- https://nodejs.org/dist/v12.22.12/node-v12.22.12-linux-x64.tar.xz | sudo tar -C /usr/local -xJf - && sudo ln -s ../node-v12.22.12-linux-x64/bin/{node,npm} /usr/local/bin/" @@ -393,7 +391,7 @@ start_services() { return 0 fi . "$VENV3DIR/bin/activate" - echo 'Starting API, controller, keepproxy, keep-web, githttpd, ws, and nginx ssl proxy...' + echo 'Starting API, controller, keepproxy, keep-web, ws, and nginx ssl proxy...' if [[ ! -d "$WORKSPACE/services/api/log" ]]; then mkdir -p "$WORKSPACE/services/api/log" fi @@ -421,9 +419,6 @@ start_services() { && python3 sdk/python/tests/run_test_server.py start_keep-web \ && checkpidfile keep-web \ && checkhealth WebDAV \ - && python3 sdk/python/tests/run_test_server.py start_githttpd \ - && checkpidfile githttpd \ - && checkhealth GitHTTP \ && python3 sdk/python/tests/run_test_server.py start_ws \ && checkpidfile ws \ && export ARVADOS_TEST_PROXY_SERVICES=1 \ @@ -444,7 +439,6 @@ stop_services() { . "$VENV3DIR/bin/activate" || return cd "$WORKSPACE" \ && python3 sdk/python/tests/run_test_server.py stop_nginx \ - && python3 sdk/python/tests/run_test_server.py stop_githttpd \ && python3 sdk/python/tests/run_test_server.py stop_ws \ && python3 sdk/python/tests/run_test_server.py stop_keep-web \ && python3 sdk/python/tests/run_test_server.py stop_keep_proxy \ @@ -466,98 +460,36 @@ interrupt() { trap interrupt INT setup_ruby_environment() { - if [[ -s "$HOME/.rvm/scripts/rvm" ]] ; then - source "$HOME/.rvm/scripts/rvm" - using_rvm=true - elif [[ -s "/usr/local/rvm/scripts/rvm" ]] ; then - source "/usr/local/rvm/scripts/rvm" - using_rvm=true - else - using_rvm=false - fi - - if [[ "$using_rvm" == true ]]; then - # If rvm is in use, we can't just put separate "dependencies" - # and "gems-under-test" paths to GEM_PATH: passenger resets - # the environment to the "current gemset", which would lose - # our GEM_PATH and prevent our test suites from running ruby - # programs (for example, the Workbench test suite could not - # boot an API server or run arv). Instead, we have to make an - # rvm gemset and use it for everything. - - [[ `type rvm | head -n1` == "rvm is a function" ]] \ - || fatal 'rvm check' - - # Put rvm's favorite path back in first place (overriding - # virtualenv, which just put itself there). Ignore rvm's - # complaint about not being in first place already. - rvm use @default 2>/dev/null - - # Create (if needed) and switch to an @arvados-tests-* gemset, - # salting the gemset name so it doesn't interfere with - # concurrent builds in other workspaces. Leave the choice of - # ruby to the caller. - gemset="arvados-tests-$(echo -n "${WORKSPACE}" | md5sum | head -c16)" - rvm use "@${gemset}" --create \ - || fatal 'rvm gemset setup' - - rvm env - (bundle version | grep -q 2.2.19) || gem install --no-document bundler -v 2.2.19 - bundle="$(which bundle)" - echo "$bundle" - "$bundle" version | grep 2.2.19 || fatal 'install bundler' - else - # When our "bundle install"s need to install new gems to - # satisfy dependencies, we want them to go where "gem install - # --user-install" would put them. (However, if the caller has - # already set GEM_HOME, we assume that's where dependencies - # should be installed, and we should leave it alone.) - - if [ -z "$GEM_HOME" ]; then - user_gempath="$(gem env gempath)" - export GEM_HOME="${user_gempath%%:*}" - fi - PATH="$(gem env gemdir)/bin:$PATH" - - # When we build and install our own gems, we install them in our - # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and - # PATH so integration tests prefer them over other versions that - # happen to be installed in $user_gempath, system dirs, etc. - - tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)" - PATH="$tmpdir_gem_home/bin:$PATH" - export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)" - - echo "Will install dependencies to $(gem env gemdir)" - echo "Will install bundler and arvados gems to $tmpdir_gem_home" - echo "Gem search path is GEM_PATH=$GEM_PATH" - bundle="bundle" - ( - export HOME=$GEMHOME - versions=(2.2.19) - for v in ${versions[@]}; do - if ! gem list --installed --version "${v}" bundler >/dev/null; then - gem install --no-document --user $(for v in ${versions[@]}; do echo bundler:${v}; done) - break - fi - done - "$bundle" version | tee /dev/stderr | grep -q 'version 2' - ) || fatal 'install bundler' - if test -d /var/lib/arvados-arvbox/ ; then - # Inside arvbox, use bundler-installed binstubs. The - # system bundler and rail's own bin/bundle refuse to work. - # I don't know why. - bundle=binstubs/bundle - fi + # When our "bundle install"s need to install new gems to + # satisfy dependencies, we want them to go where "gem install + # --user-install" would put them. (However, if the caller has + # already set GEM_HOME, we assume that's where dependencies + # should be installed, and we should leave it alone.) + + if [ -z "$GEM_HOME" ]; then + user_gempath="$(gem env gempath)" + export GEM_HOME="${user_gempath%%:*}" fi + PATH="$(gem env gemdir)/bin:$PATH" + + # When we build and install our own gems, we install them in our + # $GEMHOME tmpdir, and we want them to be at the front of GEM_PATH and + # PATH so integration tests prefer them over other versions that + # happen to be installed in $user_gempath, system dirs, etc. + + tmpdir_gem_home="$(env - PATH="$PATH" HOME="$GEMHOME" gem env gempath | cut -f1 -d:)" + PATH="$tmpdir_gem_home/bin:$PATH" + export GEM_PATH="$tmpdir_gem_home:$(gem env gempath)" + + echo "Will install dependencies to $(gem env gemdir)" + echo "Will install bundler and arvados gems to $tmpdir_gem_home" + echo "Gem search path is GEM_PATH=$GEM_PATH" + gem install --user --no-document --conservative --version '~> 2.4.0' bundler \ + || fatal 'install bundler' } with_test_gemset() { - if [[ "$using_rvm" == true ]]; then - "$@" - else - GEM_HOME="$tmpdir_gem_home" GEM_PATH="$tmpdir_gem_home" "$@" - fi + GEM_HOME="$tmpdir_gem_home" GEM_PATH="$tmpdir_gem_home" "$@" } gem_uninstall_if_exists() { @@ -622,8 +554,6 @@ initialize() { unset http_proxy https_proxy no_proxy - # Note: this must be the last time we change PATH, otherwise rvm will - # whine a lot. setup_ruby_environment echo "PATH is $PATH" @@ -636,13 +566,14 @@ install_env() { setup_virtualenv "$VENV3DIR" . "$VENV3DIR/bin/activate" - # wheel modernizes the venv (as of early 2024) and makes it more closely - # match our package build environment. + # parameterized and pytest are direct dependencies of Python tests. # PyYAML is a test requirement used by run_test_server.py and needed for # other, non-Python tests. # pdoc is needed to build PySDK documentation. + # wheel modernizes the venv (as of early 2024) and makes it more closely + # match our package build environment. # We run `setup.py build` first to generate _version.py. - pip install PyYAML pdoc wheel \ + pip install parameterized pytest PyYAML pdoc wheel \ && env -C "$WORKSPACE/sdk/python" python3 setup.py build \ && pip install "$WORKSPACE/sdk/python" \ || fatal "installing Python SDK and related dependencies failed" @@ -771,7 +702,7 @@ do_test_once() { elif [[ "$2" == "pip" ]] then tries=0 - cd "$WORKSPACE/$1" && while : + cd "$WORKSPACE/$1" && pip install . && while : do tries=$((${tries}+1)) # $3 can name a path directory for us to use, including trailing @@ -779,11 +710,13 @@ do_test_once() { if [[ -e "${3}activate" ]]; then . "${3}activate" fi - python setup.py ${short:+--short-tests-only} test ${testargs[$1]} + python3 -m pytest ${testargs[$1]} result=$? - if [[ ${tries} < 3 && ${result} == 137 ]] + # pytest uses exit code 2 to mean "test collection failed." + # See discussion in FUSE's IntegrationTest and MountTestBase. + if [[ ${tries} < 3 && ${result} == 2 ]] then - printf '\n*****\n%s tests killed -- retrying\n*****\n\n' "$1" + printf '\n*****\n%s tests exited with code 2 -- retrying\n*****\n\n' "$1" continue else break @@ -820,7 +753,7 @@ check_arvados_config() { } do_install() { - if [[ -n "${skip[install]}" || ( -n "${only_install}" && "${only_install}" != "${1}" && "${only_install}" != "${2}" ) ]]; then + if [[ -n ${skip["install_$1"]} || -n "${skip[install]}" || ( -n "${only_install}" && "${only_install}" != "${1}" && "${only_install}" != "${2}" ) ]]; then return 0 fi check_arvados_config "$1" @@ -873,11 +806,11 @@ bundle_install_trylocal() { ( set -e echo "(Running bundle install --local. 'could not find package' messages are OK.)" - if ! "$bundle" install --local --no-deployment; then + if ! bundle install --local --no-deployment; then echo "(Running bundle install again, without --local.)" - "$bundle" install --no-deployment + bundle install --no-deployment fi - "$bundle" package + bundle package ) } @@ -951,15 +884,6 @@ install_services/api() { ) || return 1 fi - cd "$WORKSPACE/services/api" \ - && rm -rf tmp/git \ - && mkdir -p tmp/git \ - && cd tmp/git \ - && tar xf ../../test/test.git.tar \ - && mkdir -p internal.git \ - && git --git-dir internal.git init \ - || return 1 - ( set -ex cd "$WORKSPACE/services/api" @@ -995,7 +919,7 @@ install_services/workbench2() { test_doc() { local arvados_api_host=pirca.arvadosapi.com && \ env -C "$WORKSPACE/doc" \ - "$bundle" exec rake linkchecker \ + bundle exec rake linkchecker \ arvados_api_host="$arvados_api_host" \ arvados_workbench_host="https://workbench.$arvados_api_host" \ baseurl="file://$WORKSPACE/doc/.site/" \ @@ -1029,12 +953,12 @@ test_arvados_version.py() { test_services/api() { rm -f "$WORKSPACE/services/api/git-commit.version" cd "$WORKSPACE/services/api" \ - && eval env RAILS_ENV=test ${short:+RAILS_TEST_SHORT=1} "$bundle" exec rake test TESTOPTS=\'-v -d\' ${testargs[services/api]} + && eval env RAILS_ENV=test ${short:+RAILS_TEST_SHORT=1} bundle exec rake test TESTOPTS=\'-v -d\' ${testargs[services/api]} } test_sdk/ruby() { cd "$WORKSPACE/sdk/ruby" \ - && "$bundle" exec rake test TESTOPTS=-v ${testargs[sdk/ruby]} + && bundle exec rake test TESTOPTS=-v ${testargs[sdk/ruby]} } test_sdk/ruby-google-api-client() { @@ -1052,7 +976,7 @@ test_sdk/R() { test_sdk/cli() { cd "$WORKSPACE/sdk/cli" \ && mkdir -p /tmp/keep \ - && KEEP_LOCAL_STORE=/tmp/keep "$bundle" exec rake test TESTOPTS=-v ${testargs[sdk/cli]} + && KEEP_LOCAL_STORE=/tmp/keep bundle exec rake test TESTOPTS=-v ${testargs[sdk/cli]} } test_sdk/java-v2() { @@ -1061,7 +985,7 @@ test_sdk/java-v2() { test_services/login-sync() { cd "$WORKSPACE/services/login-sync" \ - && "$bundle" exec rake test TESTOPTS=-v ${testargs[services/login-sync]} + && bundle exec rake test TESTOPTS=-v ${testargs[services/login-sync]} } test_services/workbench2_units() { @@ -1114,14 +1038,6 @@ install_all() { test_all() { stop_services do_test services/api - - # Shortcut for when we're only running apiserver tests. This saves a bit of time, - # because we don't need to start up the api server for subsequent tests. - if [ ! -z "$only" ] && [ "$only" == "services/api" ]; then - rotate_logfile "$WORKSPACE/services/api/log/" "test.log" - exit_cleanly - fi - do_test gofmt do_test arvados_version.py do_test doc @@ -1192,7 +1108,7 @@ if [[ -z ${interactive} ]]; then else skip=() only=() - only_install=() + only_install="" if [[ -e "$VENV3DIR/bin/activate" ]]; then stop_services; fi setnextcmd() { if [[ "$TERM" = dumb ]]; then diff --git a/cmd/arvados-client/cmd.go b/cmd/arvados-client/cmd.go index 19d13437c8..62630a6a01 100644 --- a/cmd/arvados-client/cmd.go +++ b/cmd/arvados-client/cmd.go @@ -37,19 +37,9 @@ var ( "container": cli.APICall, "container_request": cli.APICall, "group": cli.APICall, - "human": cli.APICall, - "job": cli.APICall, - "job_task": cli.APICall, - "keep_disk": cli.APICall, "keep_service": cli.APICall, "link": cli.APICall, "log": cli.APICall, - "node": cli.APICall, - "pipeline_instance": cli.APICall, - "pipeline_template": cli.APICall, - "repository": cli.APICall, - "specimen": cli.APICall, - "trait": cli.APICall, "user_agreement": cli.APICall, "user": cli.APICall, "virtual_machine": cli.APICall, diff --git a/cmd/arvados-server/arvados-git-httpd.service b/cmd/arvados-server/arvados-git-httpd.service deleted file mode 100644 index 517a75c03d..0000000000 --- a/cmd/arvados-server/arvados-git-httpd.service +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -[Unit] -Description=Arvados git server -Documentation=https://doc.arvados.org/ -After=network.target -AssertPathExists=/etc/arvados/config.yml -StartLimitIntervalSec=0 - -[Service] -Type=notify -EnvironmentFile=-/etc/arvados/environment -ExecStart=/usr/bin/arvados-git-httpd -# Set a reasonable default for the open file limit -LimitNOFILE=65536 -Restart=always -RestartSec=1 -RestartPreventExitStatus=2 - -[Install] -WantedBy=multi-user.target diff --git a/cmd/arvados-server/cmd.go b/cmd/arvados-server/cmd.go index c02b8fb57c..0f267a9b40 100644 --- a/cmd/arvados-server/cmd.go +++ b/cmd/arvados-server/cmd.go @@ -30,7 +30,6 @@ import ( "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/health" dispatchslurm "git.arvados.org/arvados.git/services/crunch-dispatch-slurm" - "git.arvados.org/arvados.git/services/githttpd" keepbalance "git.arvados.org/arvados.git/services/keep-balance" keepweb "git.arvados.org/arvados.git/services/keep-web" "git.arvados.org/arvados.git/services/keepproxy" @@ -57,7 +56,6 @@ var ( "dispatch-cloud": dispatchcloud.Command, "dispatch-lsf": lsf.DispatchCommand, "dispatch-slurm": dispatchslurm.Command, - "git-httpd": githttpd.Command, "health": healthCommand, "install": install.Command, "init": install.InitCommand, diff --git a/doc/_config.yml b/doc/_config.yml index 053922a24a..d64bc4b7dc 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -141,7 +141,6 @@ navbar: - api/methods/pipeline_instances.html.textile.liquid - api/methods/pipeline_templates.html.textile.liquid - api/methods/nodes.html.textile.liquid - - api/methods/repositories.html.textile.liquid - api/methods/keep_disks.html.textile.liquid - Metadata for bioinformatics (legacy): - api/methods/humans.html.textile.liquid @@ -243,13 +242,9 @@ navbar: - install/install-ws.html.textile.liquid - install/install-workbench2-app.html.textile.liquid - install/workbench.html.textile.liquid -# - install/install-composer.html.textile.liquid - Additional services: - install/install-shell-server.html.textile.liquid - install/install-webshell.html.textile.liquid - - install/install-arv-git-httpd.html.textile.liquid -# - Containers API (all): -# - install/install-jobs-image.html.textile.liquid - Containers API (cloud): - install/crunch2-cloud/install-compute-node.html.textile.liquid - install/crunch2-cloud/install-dispatch-cloud.html.textile.liquid diff --git a/doc/_includes/_container_glob_patterns.liquid b/doc/_includes/_container_glob_patterns.liquid new file mode 100644 index 0000000000..4015e16220 --- /dev/null +++ b/doc/_includes/_container_glob_patterns.liquid @@ -0,0 +1,27 @@ +{% comment %} +Copyright (C) The Arvados Authors. All rights reserved. + +SPDX-License-Identifier: CC-BY-SA-3.0 +{% endcomment %} + +h2. Glob patterns + +Each pattern in the @output_glob@ array can include the following special terms: + +table(table table-bordered table-condensed). +|@*@|matches any sequence of non-@/@ characters| +|@?@|matches any single non-@/@ character| +|@[abcde]@ or @[a-e]@|matches any non-@/@ character in @abcde@| +|@[^abcde]@ or @[^a-e]@ or +@[!abcde]@ or @[!a-e]@|matches any non-@/@ character other than @abcde@| +|@/**/@|matches zero or more levels of subdirectories| +|@**/@|at the beginning of a pattern, matches zero or more directories| +|@/**@|at the end of a pattern, matches any file in any subdirectory| + +Example patterns: + +table(table table-bordered table-condensed). +|@*.txt@|matches files with extension @.txt@ at the top level| +|@foo/**@|matches the entire tree rooted at @foo@ in the top level| +|@**/fo[og]@|matches all files named @foo@ or @fog@ anywhere in the tree| +|@foo/**/*.txt@|matches all files with extension @.txt@ anywhere in the tree rooted at @foo@ in the top level| diff --git a/doc/_includes/_install_ruby_and_bundler.liquid b/doc/_includes/_install_ruby_and_bundler.liquid index 5d5bc9e9d7..4381d9fedf 100644 --- a/doc/_includes/_install_ruby_and_bundler.liquid +++ b/doc/_includes/_install_ruby_and_bundler.liquid @@ -6,14 +6,7 @@ SPDX-License-Identifier: CC-BY-SA-3.0 Ruby 2.7 or newer is required. -* "Option 1: Install from packages":#packages -* "Option 2: Install with RVM":#rvm - -h2(#packages). Option 1: Install from packages - -h3. Alma/CentOS/Red Hat/Rocky - -Version 7 of these distributions does not provide a new enough Ruby version. Use "RVM":#rvm to install Ruby 2.7 or newer. +h2. Alma/CentOS/Red Hat/Rocky Version 8 of these distributions provides Ruby 2.7. You can install it by running: @@ -22,63 +15,10 @@ Version 8 of these distributions provides Ruby 2.7. You can install it by runnin # dnf install --enablerepo=devel ruby ruby-devel -h3. Debian and Ubuntu - -Debian 10 (buster) and Ubuntu 18.04 (bionic) ship with Ruby 2.5, which is too old for Arvados. Use "RVM":#rvm to install Ruby 2.7 or newer. +h2. Debian and Ubuntu Debian 11 (bullseye) and Ubuntu 20.04 (focal) and later ship with Ruby 2.7 or newer, which is sufficient for Arvados.
# apt-get --no-install-recommends install ruby ruby-dev
- -h2(#rvm). Option 2: Install with RVM - -{% include 'notebox_begin_warning' %} -We do not recommend using RVM unless the Ruby version provided by your OS distribution is older than 2.7. -{% include 'notebox_end' %} - -h3. Install gpg and curl - -h4. CentOS/Red Hat 7 - -
-yum install gpg curl which findutils procps
-
- -{% comment %} -To build ruby 3.2.2 on CentOS 7, add: "yum --enablerepo=powertools install libyaml-devel" -{% endcomment %} - -h4. Alma/CentOS/Red Hat/Rocky 8+ - -
-dnf install gpg curl which findutils procps
-
- -h4. Debian and Ubuntu - -
-apt-get --no-install-recommends install gpg curl ca-certificates dirmngr procps
-
- -h3. Install RVM, Ruby and Bundler - - -
gpg --keyserver pgp.mit.edu --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB
-\curl -sSL https://get.rvm.io | bash -s stable --ruby=2.7.7
-
- -This command installs the Ruby 2.7.7 release, as well as the @gem@ and @bundle@ commands. - -To use Ruby installed from RVM, load it in an open shell like this: - - -
source /usr/local/rvm/scripts/rvm
-
- -Alternately you can use @rvm-exec@ (the first parameter is the ruby version to use, or "default"), for example: - - -
rvm-exec default ruby -v
-
diff --git a/doc/_includes/_mount_types.liquid b/doc/_includes/_mount_types.liquid index 86e05be866..f22f7d3551 100644 --- a/doc/_includes/_mount_types.liquid +++ b/doc/_includes/_mount_types.liquid @@ -24,15 +24,6 @@ At container startup, the target path will have the same directory structure as "kind":"collection", "uuid":"..." }| -|Git tree|@git_tree@|@"uuid"@ must be the UUID of an Arvados-hosted git repository. -@"commit"@ must be a full 40-character commit hash. -@"path"@, if provided, must be "/". -At container startup, the target path will have the source tree indicated by the given commit. The @.git@ metadata directory _will not_ be available.|
{
- "kind":"git_tree",
- "uuid":"zzzzz-s0uqq-xxxxxxxxxxxxxxx",
- "commit":"f315c59f90934cccae6381e72bba59d27ba42099"
-}
-
| |Temporary directory|@tmp@|@"capacity"@: capacity (in bytes) of the storage device. @"device_type"@ (optional, default "network"): one of @{"ram", "ssd", "disk", "network"}@ indicating the acceptable level of performance. (*note: not yet implemented as of v1.5*) At container startup, the target path will be empty. When the container finishes, the content will be discarded. This will be backed by a storage mechanism no slower than the specified type.|
{
diff --git a/doc/_includes/_ssh_intro.liquid b/doc/_includes/_ssh_intro.liquid
index 8cb09f135f..4bf72c1b31 100644
--- a/doc/_includes/_ssh_intro.liquid
+++ b/doc/_includes/_ssh_intro.liquid
@@ -5,7 +5,7 @@ SPDX-License-Identifier: CC-BY-SA-3.0
 {% endcomment %}
 
 
-Arvados requires a public SSH key in order to securely log in to an Arvados VM instance, or to access an Arvados Git repository. The three sections below help you get started:
+Arvados requires a public SSH key in order to securely log in to an Arvados VM instance. The three sections below help you get started:
 
 # "Getting your SSH key":#gettingkey
 # "Adding your key to Arvados Workbench":#workbench
diff --git a/doc/_includes/_tutorial_git_repo_expectations.liquid b/doc/_includes/_tutorial_git_repo_expectations.liquid
deleted file mode 100644
index 8a172de283..0000000000
--- a/doc/_includes/_tutorial_git_repo_expectations.liquid
+++ /dev/null
@@ -1,9 +0,0 @@
-{% comment %}
-Copyright (C) The Arvados Authors. All rights reserved.
-
-SPDX-License-Identifier: CC-BY-SA-3.0
-{% endcomment %}
-
-{% include 'notebox_begin' %}
-This tutorial assumes that you have a working Arvados repository. If you do not have a repository created, you can follow the instructions in the "Adding a new repository":{{site.baseurl}}/user/tutorials/add-new-repository.html page. We will use the *$USER/tutorial* repository created in that page as the example.
-{% include 'notebox_end' %}
diff --git a/doc/admin/config-urls.html.textile.liquid b/doc/admin/config-urls.html.textile.liquid
index 3cf6e79722..e2d1404332 100644
--- a/doc/admin/config-urls.html.textile.liquid
+++ b/doc/admin/config-urls.html.textile.liquid
@@ -31,7 +31,6 @@ table(table table-bordered table-condensed).
 |controller     |yes                    |yes|yes ^2,4^|InternalURLs used by reverse proxy and container shell connections|
 |arvados-dispatch-cloud|no              |yes|no ^3^|InternalURLs only used to expose Prometheus metrics|
 |arvados-dispatch-lsf|no                |yes|no ^3^|InternalURLs only used to expose Prometheus metrics|
-|git-http       |yes                    |yes|no ^2^|InternalURLs only used by reverse proxy (e.g. Nginx)|
 |git-ssh        |yes                    |no |no    ||
 |keepproxy      |yes                    |yes|no ^2^|InternalURLs only used by reverse proxy (e.g. Nginx)|
 |keepstore      |no                     |yes|yes   |All clients connect to InternalURLs|
@@ -174,10 +173,7 @@ server {
   index  index.html index.htm index.php;
 
   passenger_enabled on;
-
-  # If you are using RVM, uncomment the line below.
-  # If you're using system ruby, leave it commented out.
-  #passenger_ruby /usr/local/rvm/wrappers/default/ruby;
+  passenger_preload_bundler on;
 
   # This value effectively limits the size of API objects users can
   # create, especially collections.  If you change this, you should
diff --git a/doc/admin/inspect.html.textile.liquid b/doc/admin/inspect.html.textile.liquid
index fff94cb55f..601d26c5cb 100644
--- a/doc/admin/inspect.html.textile.liquid
+++ b/doc/admin/inspect.html.textile.liquid
@@ -25,7 +25,6 @@ table(table table-bordered table-condensed table-hover){width:40em}.
 |arvados-controller|✓|
 |arvados-dispatch-cloud|✓|
 |arvados-dispatch-lsf|✓|
-|arvados-git-httpd||
 |arvados-ws|✓|
 |composer||
 |keepproxy|✓|
diff --git a/doc/admin/management-token.html.textile.liquid b/doc/admin/management-token.html.textile.liquid
index a4939b740c..5650c5038d 100644
--- a/doc/admin/management-token.html.textile.liquid
+++ b/doc/admin/management-token.html.textile.liquid
@@ -21,7 +21,6 @@ h2. API server and other services
 The following services also support monitoring.
 
 * API server
-* arvados-git-httpd
 * controller
 * keep-balance
 * keepproxy
diff --git a/doc/admin/metrics.html.textile.liquid b/doc/admin/metrics.html.textile.liquid
index ed9fbbd7ae..113536ff58 100644
--- a/doc/admin/metrics.html.textile.liquid
+++ b/doc/admin/metrics.html.textile.liquid
@@ -35,9 +35,7 @@ table(table table-bordered table-condensed table-hover).
 |arvados-controller|✓|
 |arvados-dispatch-cloud|✓|
 |arvados-dispatch-lsf|✓|
-|arvados-git-httpd||
 |arvados-ws|✓|
-|composer||
 |keepproxy|✓|
 |keepstore|✓|
 |keep-balance|✓|
diff --git a/doc/admin/upgrading.html.textile.liquid b/doc/admin/upgrading.html.textile.liquid
index 64a113b6f8..23b701dcd1 100644
--- a/doc/admin/upgrading.html.textile.liquid
+++ b/doc/admin/upgrading.html.textile.liquid
@@ -32,6 +32,21 @@ h2(#main). development main
 
 "previous: Upgrading to 2.7.1":#v2_7_1
 
+h3. Legacy container logging system has been removed
+
+The following configuration keys are no longer supported. Remove them from your @/etc/arvados/config.yml@ file to avoid warnings when services start up.
+* @Containers.Logging.LimitLogBytesPerJob@
+* @Containers.Logging.LogBytesPerEvent@
+* @Containers.Logging.LogPartialLineThrottlePeriod@
+* @Containers.Logging.LogSecondsBetweenEvents@
+* @Containers.Logging.LogThrottleBytes@
+* @Containers.Logging.LogThrottleLines@
+* @Containers.Logging.LogThrottlePeriod@
+* @Containers.Logging.MaxAge@
+* @Containers.Logging.SweepInterval@
+
+Any container logging content remaining in the database from the legacy system will be deleted.
+
 h3. Virtual environments inside distribution Python packages have moved
 
 The distribution packages that we publish for Python packages include an entire virtualenv with all required libraries. In Arvados 3.0 these virtualenvs have moved from @/usr/share/python3/dist/PACKAGE_NAME@ to @/usr/lib/PACKAGE_NAME@ to prevent conflicts with distribution packages and better conform to filesystem standards.
@@ -142,7 +157,7 @@ We have introduced a small exception to the previous behavior of "Arvados API to
 
 h3. Deprecated/legacy APIs slated for removal
 
-The legacy APIs "humans":../api/methods/humans.html, "specimens":../api/methods/specimens.html, "traits":../api/methods/traits.html, "jobs":../api/methods/jobs.html, "job_tasks":../api/methods/job_tasks.html, "pipeline_instances":../api/methods/pipeline_instances.html, "pipeline_templates":../api/methods/pipeline_templates.html, "nodes":../api/methods/nodes.html, "repositories":../api/methods/repositories.html, and "keep_disks":../api/methods/keep_disks.html are deprecated and will be removed in a future major version of Arvados.
+The legacy APIs "humans":https://doc.arvados.org/v2.7/api/methods/humans.html, "specimens":https://doc.arvados.org/v2.7/api/methods/specimens.html, "traits":https://doc.arvados.org/v2.7/api/methods/traits.html, "jobs":https://doc.arvados.org/v2.7/api/methods/jobs.html, "job_tasks":https://doc.arvados.org/v2.7/api/methods/job_tasks.html, "pipeline_instances":https://doc.arvados.org/v2.7/api/methods/pipeline_instances.html, "pipeline_templates":https://doc.arvados.org/v2.7/api/methods/pipeline_templates.html, "nodes":https://doc.arvados.org/v2.7/api/methods/nodes.html, "repositories":https://doc.arvados.org/v2.7/api/methods/repositories.html, and "keep_disks":https://doc.arvados.org/v2.7/api/methods/keep_disks.html are deprecated and will be removed in a future major version of Arvados.
 
 In addition, the @default_owner_uuid@, @api_client_id@, and @user_id@ fields of "api_client_authorizations":../api/methods/api_client_authorizations.html are deprecated and will be removed from @api_client_authorization@ responses in a future major version of Arvados.  This should not affect clients as  @default_owner_uuid@ was never implemented, and @api_client_id@ and @user_id@ returned internal ids that were not meaningful or usable with any other API call.
 
diff --git a/doc/admin/user-management-cli.html.textile.liquid b/doc/admin/user-management-cli.html.textile.liquid
index c2d4743ddf..dea705ddaa 100644
--- a/doc/admin/user-management-cli.html.textile.liquid
+++ b/doc/admin/user-management-cli.html.textile.liquid
@@ -144,23 +144,3 @@ read -rd $'\000' newlink <
-
-h3. Git repository
-
-Give @$user_uuid@ permission to commit to @$repo_uuid@ as @$repo_username@
-
-
-user_uuid=xxxxxxxchangeme
-repo_uuid=xxxxxxxchangeme
-repo_username=xxxxxxxchangeme
-
-read -rd $'\000' newlink <
diff --git a/doc/admin/user-management.html.textile.liquid b/doc/admin/user-management.html.textile.liquid
index 7d30ee88d1..994081901c 100644
--- a/doc/admin/user-management.html.textile.liquid
+++ b/doc/admin/user-management.html.textile.liquid
@@ -60,7 +60,6 @@ notextile. 
# A new user record is not set up, and not active. An inactive user cannot create or update any object, but can read Arvados objects that the user account has permission to read (such as publicly available items readable by the "anonymous" user). # Using Workbench or the "command line":{{site.baseurl}}/admin/user-management-cli.html , the admin invokes @setup@ on the user. The setup method adds the user to the "All users" group. - If "Users.AutoSetupNewUsers":config.html is true, this happens automatically during user creation, so in that case new users start at step (3). -- If "Users.AutoSetupNewUsersWithRepository":config.html is true, a new git repo is created for the user. - If "Users.AutoSetupNewUsersWithVmUUID":config.html is set, the user is given login permission to the specified shell node # User is set up, but still not yet active. The browser presents "user agreements":#user_agreements (if any) and then invokes the user @activate@ method on the user's behalf. # The user @activate@ method checks that all "user agreements":#user_agreements are signed. If so, or there are no user agreements, the user is activated. diff --git a/doc/api/crunch-scripts.html.textile.liquid b/doc/api/crunch-scripts.html.textile.liquid deleted file mode 100644 index a0d244d9bc..0000000000 --- a/doc/api/crunch-scripts.html.textile.liquid +++ /dev/null @@ -1,54 +0,0 @@ ---- -layout: default -navsection: api -navmenu: Concepts -title: Crunch scripts - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "container requests.":methods/container_requests.html -{% include 'notebox_end' %} - -h2. Crunch scripts - -A crunch script is responsible for completing a single JobTask. In doing so, it will: - -* (optionally) read some input from Keep -* (optionally) store some output in Keep -* (optionally) create some new JobTasks and add them to the current Job -* (optionally) update the current JobTask record with the "output" attribute set to a Keep locator or a fragment of a manifest -* update the current JobTask record with the "success" attribute set to True - -A task's context is provided in environment variables. - -table(table table-bordered table-condensed). -|Environment variable|Description| -|@JOB_UUID@|UUID of the current "Job":methods/jobs.html| -|@TASK_UUID@|UUID of the current "JobTask":methods/job_tasks.html| -|@ARVADOS_API_HOST@|Hostname and port number of API server| -|@ARVADOS_API_TOKEN@|Authentication token to use with API calls made by the current task| - -The crunch script typically uses the Python SDK (or another suitable client library / SDK) to connect to the Arvados service and retrieve the rest of the details about the current job and task. - -The Python SDK has some shortcuts for common operations. - -In general, a crunch script can access information about the current job and task like this: - -
-import arvados
-import os
-
-job = arvados.api().jobs().get(uuid=os.environ['JOB_UUID']).execute()
-$sys.stderr.write("script_parameters['foo'] == %s"
-                  % job['script_parameters']['foo'])
-
-task = arvados.api().job_tasks().get(uuid=os.environ['TASK_UUID']).execute()
-$sys.stderr.write("current task sequence number is %d"
-                  % task['sequence'])
-
diff --git a/doc/api/methods/container_requests.html.textile.liquid b/doc/api/methods/container_requests.html.textile.liquid index 1c269fb3e6..38eb4909be 100644 --- a/doc/api/methods/container_requests.html.textile.liquid +++ b/doc/api/methods/container_requests.html.textile.liquid @@ -49,6 +49,8 @@ table(table table-bordered table-condensed). |cwd|string|Initial working directory, given as an absolute path (in the container) or a path relative to the WORKDIR given in the image's Dockerfile.|Required.| |command|array of strings|Command to execute in the container.|Required. e.g., @["echo","hello"]@| |output_path|string|Path to a directory or file inside the container that should be preserved as container's output when it finishes. This path must be one of the mount targets. For best performance, point output_path to a writable collection mount. See "Pre-populate output using Mount points":#pre-populate-output for details regarding optional output pre-population using mount points and "Symlinks in output":#symlinks-in-output for additional details.|Required.| +|output_glob|array of strings|Glob patterns determining which files (of those present in the output directory when the container finishes) will be included in the output collection. If multiple patterns are given, files that match any pattern are included. If null or empty, all files will be included.|e.g., @["**/*.vcf", "**/*.vcf.gz"]@ +See "Glob patterns":#glob_patterns for more details.| |output_name|string|Desired name for the output collection. If null or empty, a name will be assigned automatically.|| |output_ttl|integer|Desired lifetime for the output collection, in seconds. If zero, the output collection will not be deleted automatically.|| |priority|integer|Range 0-1000. Indicate scheduling order preference.|Clients are expected to submit container requests with zero priority in order to preview the container that will be used to satisfy it. Priority can be null if and only if state!="Committed". See "below for more details":#priority .| @@ -138,6 +140,8 @@ h2(#runtime_constraints). {% include 'container_runtime_constraints' %} h2(#scheduling_parameters). {% include 'container_scheduling_parameters' %} +h2(#glob_patterns). {% include 'container_glob_patterns' %} + h2(#container_reuse). Container reuse When a container request is "Committed", the system will try to find and reuse an existing Container with the same command, cwd, environment, output_path, container_image, mounts, secret_mounts, runtime_constraints, runtime_user_uuid, and runtime_auth_scopes being requested. diff --git a/doc/api/methods/containers.html.textile.liquid b/doc/api/methods/containers.html.textile.liquid index 1d2fed768c..776d4098c5 100644 --- a/doc/api/methods/containers.html.textile.liquid +++ b/doc/api/methods/containers.html.textile.liquid @@ -30,9 +30,10 @@ table(table table-bordered table-condensed). |finished_at|datetime|When this container finished.|Null if container has not yet finished.| |log|string|Portable data hash of a collection containing the log messages produced when executing the container.|Null if container has not yet started. The Crunch system will periodically update this field for a running container.| |environment|hash|Environment variables and values that should be set in the container environment (@docker run --env@). This augments and (when conflicts exist) overrides environment variables given in the image's Dockerfile.|Must be equal to a ContainerRequest's environment in order to satisfy the ContainerRequest.| -|cwd|string|Initial working directory.|Must be equal to a ContainerRequest's cwd in order to satisfy the ContainerRequest| +|cwd|string|Initial working directory.|Must be equal to a ContainerRequest's cwd in order to satisfy the ContainerRequest.| |command|array of strings|Command to execute.| Must be equal to a ContainerRequest's command in order to satisfy the ContainerRequest.| |output_path|string|Path to a directory or file inside the container that should be preserved as this container's output when it finishes.|Must be equal to a ContainerRequest's output_path in order to satisfy the ContainerRequest.| +|output_glob|array of strings|Glob patterns determining which files will be included in the output collection. See corresponding attribute in the "container_requests resource":container_requests.html.|Must be equal to a ContainerRequest's output_glob in order to satisfy the ContainerRequest. See "Glob patterns":#glob_patterns for more details.| |mounts|hash|Must contain the same keys as the ContainerRequest being satisfied. Each value must be within the range of values described in the ContainerRequest at the time the Container is assigned to the ContainerRequest.|See "Mount types":#mount_types for more details.| |secret_mounts|hash|Must contain the same keys as the ContainerRequest being satisfied. Each value must be within the range of values described in the ContainerRequest at the time the Container is assigned to the ContainerRequest.|Not returned in API responses. Reset to empty when state is "Complete" or "Cancelled".| |runtime_constraints|hash|Compute resources, and access to the outside world, that are / were available to the container. @@ -97,6 +98,8 @@ table(table table-bordered table-condensed). h2(#scheduling_parameters). {% include 'container_scheduling_parameters' %} +h2(#glob_patterns). {% include 'container_glob_patterns' %} + h2. Methods See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. diff --git a/doc/api/methods/humans.html.textile.liquid b/doc/api/methods/humans.html.textile.liquid deleted file mode 100644 index 1c338217eb..0000000000 --- a/doc/api/methods/humans.html.textile.liquid +++ /dev/null @@ -1,85 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "humans" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and is slated to be removed entirely in a future major release of Arvados. The recommended way to store metadata is with "'properties' field on collections and projects.":../properties.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/humans@ - -Object type: @7a9it@ - -Example UUID: @zzzzz-7a9it-0123456789abcde@ - -h2. Resource - -A metadata record that may be used to represent a human subject. - -Each Human has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|properties|hash||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new Human. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|human|object||query|| - -h3. delete - -Delete an existing Human. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Human in question.|path|| - -h3. get - -Gets a Human's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Human in question.|path|| - -h3. list - -List humans. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing Human. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Human in question.|path|| -|human|object||query|| diff --git a/doc/api/methods/job_tasks.html.textile.liquid b/doc/api/methods/job_tasks.html.textile.liquid deleted file mode 100644 index 880fe56219..0000000000 --- a/doc/api/methods/job_tasks.html.textile.liquid +++ /dev/null @@ -1,101 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "job_tasks" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "container requests.":container_requests.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/job_tasks@ - -Object type: @ot0gb@ - -Example UUID: @zzzzz-ot0gb-0123456789abcde@ - -h2. Resource - -Deprecated. - -A job task is a individually scheduled unit of work executed as part of an overall job. - -Each JobTask has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|sequence|integer|Execution sequence. -A step cannot be run until all steps with lower sequence numbers have completed. -Job steps with the same sequence number can be run in any order.|| -|parameters|hash||| -|output|text||| -|progress|float||| -|success|boolean|Is null if the task has neither completed successfully nor failed permanently.|| - -The following attributes should not be updated by anyone other than the job manager: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Notes| -|qsequence|integer|Order of arrival|0-based| -|job_uuid|string||| -|created_by_job_task_uuid|string||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new JobTask. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|job_task|object||query|| - -h3. delete - -Delete an existing JobTask. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the JobTask in question.|path|| - -h3. get - -Gets a JobTask's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the JobTask in question.|path|| - -h3. list - -List job_tasks. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing JobTask. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the JobTask in question.|path|| -|job_task|object||query|| diff --git a/doc/api/methods/jobs.html.textile.liquid b/doc/api/methods/jobs.html.textile.liquid deleted file mode 100644 index 75d7368c8e..0000000000 --- a/doc/api/methods/jobs.html.textile.liquid +++ /dev/null @@ -1,290 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "jobs" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "container requests.":container_requests.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/jobs@ - -Object type: @8i9sb@ - -Example UUID: @zzzzz-8i9sb-0123456789abcde@ - -h2. Resource - -A job describes a work order to be executed by the Arvados cluster. - -Each job has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Notes| -|script|string|The filename of the job script.|This program will be invoked by Crunch for each job task. It is given as a path to an executable file, relative to the @/crunch_scripts@ directory in the Git tree specified by the _repository_ and _script_version_ attributes.| -|script_parameters|hash|The input parameters for the job.|Conventionally, one of the parameters is called @"input"@. Typically, some parameter values are collection UUIDs. Ultimately, though, the significance of parameters is left entirely up to the script itself.| -|repository|string|Git repository name or URL.|Source of the repository where the given script_version is to be found. This can be given as the name of a locally hosted repository, or as a publicly accessible URL starting with @git://@, @http://@, or @https://@. -Examples: -@yourusername/yourrepo@ -@https://github.com/arvados/arvados.git@| -|script_version|string|Git commit|During a **create** transaction, this is the Git branch, tag, or hash supplied by the client. Before the job starts, Arvados updates it to the full 40-character SHA-1 hash of the commit used by the job. -See "Specifying Git versions":#script_version below for more detail about acceptable ways to specify a commit.| -|cancelled_by_client_uuid|string|API client ID|Is null if job has not been cancelled| -|cancelled_by_user_uuid|string|Authenticated user ID|Is null if job has not been cancelled| -|cancelled_at|datetime|When job was cancelled|Is null if job has not been cancelled| -|started_at|datetime|When job started running|Is null if job has not [yet] started| -|finished_at|datetime|When job finished running|Is null if job has not [yet] finished| -|running|boolean|Whether the job is running|| -|success|boolean|Whether the job indicated successful completion|Is null if job has not finished| -|is_locked_by_uuid|string|UUID of the user who has locked this job|Is null if job is not locked. The system user locks the job when starting the job, in order to prevent job attributes from being altered.| -|node_uuids|array|List of UUID strings for node objects that have been assigned to this job|| -|log|string|Collection UUID|Is null if the job has not finished. After the job runs, the given collection contains a text file with log messages provided by the @arv-crunch-job@ task scheduler as well as the standard error streams provided by the task processes.| -|tasks_summary|hash|Summary of task completion states.|Example: @{"done":0,"running":4,"todo":2,"failed":0}@| -|output|string|Collection UUID|Is null if the job has not finished.| -|nondeterministic|boolean|The job is expected to produce different results if run more than once.|If true, this job will not be considered as a candidate for automatic re-use when submitting subsequent identical jobs.| -|submit_id|string|Unique ID provided by client when job was submitted|Optional. This can be used by a client to make the "jobs.create":{{site.baseurl}}/api/methods/jobs.html#create method idempotent.| -|priority|string||| -|arvados_sdk_version|string|Git commit hash that specifies the SDK version to use from the Arvados repository|This is set by searching the Arvados repository for a match for the arvados_sdk_version runtime constraint.| -|docker_image_locator|string|Portable data hash of the collection that contains the Docker image to use|This is set by searching readable collections for a match for the docker_image runtime constraint.| -|runtime_constraints|hash|Constraints that must be satisfied by the job/task scheduler in order to run the job.|See below.| -|components|hash|Name and uuid pairs representing the child work units of this job. The uuids can be of different object types.|Example components hash: @{"name1": "zzzzz-8i9sb-xyz...", "name2": "zzzzz-d1hrv-xyz...",}@| - -h3(#script_version). Specifying Git versions - -The script_version attribute and arvados_sdk_version runtime constraint are typically given as a branch, tag, or commit hash, but there are many more ways to specify a Git commit. The "specifying revisions" section of the "gitrevisions manual page":http://git-scm.com/docs/gitrevisions.html has a definitive list. Arvados accepts Git versions in any format listed there that names a single commit (not a tree, a blob, or a range of commits). However, some kinds of names can be expected to resolve differently in Arvados than they do in your local repository. For example, HEAD@{1} refers to the local reflog, and @origin/main@ typically refers to a remote branch: neither is likely to work as desired if given as a Git version. - -h3. Runtime constraints - -table(table table-bordered table-condensed). -|_. Key|_. Type|_. Description|_. Implemented| -|arvados_sdk_version|string|The Git version of the SDKs to use from the Arvados git repository. See "Specifying Git versions":#script_version for more detail about acceptable ways to specify a commit. If you use this, you must also specify a @docker_image@ constraint (see below). In order to install the Python SDK successfully, Crunch must be able to find and run virtualenv inside the container.|✓| -|docker_image|string|The Docker image that this Job needs to run. If specified, Crunch will create a Docker container from this image, and run the Job's script inside that. The Keep mount and work directories will be available as volumes inside this container. The image must be uploaded to Arvados using @arv keep docker@. You may specify the image in any format that Docker accepts, such as @arvados/jobs@, @debian:latest@, or the Docker image id. Alternatively, you may specify the portable data hash of the image Collection.|✓| -|min_nodes|integer||✓| -|max_nodes|integer||| -|min_cores_per_node|integer|Require that each node assigned to this Job have the specified number of CPU cores|✓| -|min_ram_mb_per_node|integer|Require that each node assigned to this Job have the specified amount of real memory (in MiB)|✓| -|min_scratch_mb_per_node|integer|Require that each node assigned to this Job have the specified amount of scratch storage available (in MiB)|✓| -|max_tasks_per_node|integer|Maximum simultaneous tasks on a single node|✓| -|keep_cache_mb_per_task|integer|Size of file data buffer for per-task Keep directory ($TASK_KEEPMOUNT), in MiB. Default is 256 MiB. Increase this to reduce cache thrashing in situtations such as accessing multiple large (64+ MiB) files at the same time, or accessing different parts of a large file at the same time.|✓| -|min_ram_per_task|integer|Minimum real memory (KiB) per task|| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. cancel - -Cancel a job that is queued or running. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string||path|| - -h3(#create). create - -Create a new Job. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|job|object|Job resource|request body|| -|minimum_script_version |string |Git branch, tag, or commit hash specifying the minimum acceptable script version (earliest ancestor) to consider when deciding whether to re-use a past job.[1]|query|@"c3e86c9"@| -|exclude_script_versions|array of strings|Git commit branches, tags, or hashes to exclude when deciding whether to re-use a past job.|query|@["8f03c71","8f03c71"]@ -@["badtag1","badtag2"]@| -|filters|array of arrays|Conditions to find Jobs to reuse.|query|| -|find_or_create |boolean |Before creating, look for an existing job that has identical script, script_version, and script_parameters to those in the present job, has nondeterministic=false, and did not fail (it could be queued, running, or completed). If such a job exists, respond with the existing job instead of submitting a new one.|query|@false@| - -When a job is submitted to the queue using the **create** method, the @script_version@ attribute is updated to a full 40-character Git commit hash based on the current content of the specified repository. If @script_version@ cannot be resolved, the job submission is rejected. - -fn1. See the "note about specifying Git commits":#script_version for more detail. - -h4. Specialized filters - -Special filter operations are available for specific Job columns. - -* @script_version@ @in git@ @REFSPEC@, @arvados_sdk_version@ @in git@ @REFSPEC@
Resolve @REFSPEC@ to a list of Git commits, and match jobs with a @script_version@ or @arvados_sdk_version@ in that list. When creating a job and filtering @script_version@, the search will find commits between @REFSPEC@ and the submitted job's @script_version@; all other searches will find commits between @REFSPEC@ and HEAD. This list may include parallel branches if there is more than one path between @REFSPEC@ and the end commit in the graph. Use @not in@ or @not in git@ filters (below) to blacklist specific commits. - -* @script_version@ @not in git@ @REFSPEC@, @arvados_sdk_version@ @not in git@ @REFSPEC@
Resolve @REFSPEC@ to a list of Git commits, and match jobs with a @script_version@ or @arvados_sdk_version@ not in that list. - -* @docker_image_locator@ @in docker@ @SEARCH@
@SEARCH@ can be a Docker image hash, a repository name, or a repository name and tag separated by a colon (@:@). The server will find collections that contain a Docker image that match that search criteria, then match jobs with a @docker_image_locator@ in that list. - -* @docker_image_locator@ @not in docker@ @SEARCH@
Negate the @in docker@ filter. - -h4. Reusing jobs - -Because Arvados records the exact version of the script, input parameters, and runtime environment that was used to run the job, if the script is deterministic (meaning that the same code version is guaranteed to produce the same outputs from the same inputs) then it is possible to re-use the results of past jobs, and avoid re-running the computation to save time. Arvados uses the following algorithm to determine if a past job can be re-used: - -notextile.
- -# If @find_or_create@ is false or omitted, create a new job and skip the rest of these steps. -# If @filters@ are specified, find jobs that match those filters. If any filters are given, there must be at least one filter on the @repository@ attribute and one on the @script@ attribute: otherwise an error is returned. -# If @filters@ are not specified, find jobs with the same @repository@ and @script@, with a @script_version@ between @minimum_script_version@ and @script_version@ inclusively (excluding @excluded_script_versions@), and a @docker_image_locator@ with the latest Collection that matches the submitted job's @docker_image@ constraint. If the submitted job includes an @arvados_sdk_version@ constraint, jobs must have an @arvados_sdk_version@ between that refspec and HEAD to be found. *This form is deprecated: use filters instead.* -# If the found jobs include a completed job, and all found completed jobs have consistent output, return one of them. Which specific job is returned is undefined. -# If the found jobs only include incomplete jobs, return one of them. Which specific job is returned is undefined. -# If no job has been returned so far, create and return a new job. - -
- -h4. Examples - -Run the script "crunch_scripts/hash.py" in the repository "you" using the "main" commit. Arvados should re-use a previous job if the script_version of the previous job is the same as the current "main" commit. This works irrespective of whether the previous job was submitted using the name "main", a different branch name or tag indicating the same commit, a SHA-1 commit hash, etc. - -
-{
-  "job": {
-    "script": "hash.py",
-    "repository": "you/you",
-    "script_version": "main",
-    "script_parameters": {
-      "input": "c1bad4b39ca5a924e481008009d94e32+210"
-    }
-  },
-  "find_or_create": true
-}
-
- -Run using exactly the version "d00220fb38d4b85ca8fc28a8151702a2b9d1dec5". Arvados should re-use a previous job if the "script_version" of that job is also "d00220fb38d4b85ca8fc28a8151702a2b9d1dec5". - -
-{
-  "job": {
-    "script": "hash.py",
-    "repository": "you/you",
-    "script_version": "d00220fb38d4b85ca8fc28a8151702a2b9d1dec5",
-    "script_parameters": {
-      "input": "c1bad4b39ca5a924e481008009d94e32+210"
-    }
-  },
-  "find_or_create": true
-}
-
- -Arvados should re-use a previous job if the "script_version" of the previous job is between "earlier_version_tag" and the "main" commit (inclusive), but not the commit indicated by "blacklisted_version_tag". If there are no previous jobs matching these criteria, run the job using the "main" commit. - -
-{
-  "job": {
-    "script": "hash.py",
-    "repository": "you/you",
-    "script_version": "main",
-    "script_parameters": {
-      "input": "c1bad4b39ca5a924e481008009d94e32+210"
-    }
-  },
-  "minimum_script_version": "earlier_version_tag",
-  "exclude_script_versions": ["blacklisted_version_tag"],
-  "find_or_create": true
-}
-
- -The same behavior, using filters: - -
-{
-  "job": {
-    "script": "hash.py",
-    "repository": "you/you",
-    "script_version": "main",
-    "script_parameters": {
-      "input": "c1bad4b39ca5a924e481008009d94e32+210"
-    }
-  },
-  "filters": [["script", "=", "hash.py"],
-              ["repository", "=", "you/you"],
-              ["script_version", "in git", "earlier_version_tag"],
-              ["script_version", "not in git", "blacklisted_version_tag"]],
-  "find_or_create": true
-}
-
- -Run the script "crunch_scripts/monte-carlo.py" in the repository "you/you" using the current "main" commit. Because it is marked as "nondeterministic", this job will not be considered as a suitable candidate for future job submissions that use the "find_or_create" feature. - -
-{
-  "job": {
-    "script": "monte-carlo.py",
-    "repository": "you/you",
-    "script_version": "main",
-    "nondeterministic": true,
-    "script_parameters": {
-      "input": "c1bad4b39ca5a924e481008009d94e32+210"
-    }
-  }
-}
-
- -h3. delete - -Delete an existing Job. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Job in question.|path|| - -h3. get - -Gets a Job's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Job in question.|path|| - -h3. list - -List jobs. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -See the create method documentation for more information about Job-specific filters. - -h3. log_tail_follow - -log_tail_follow jobs - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string||path|| -|buffer_size|integer (default 8192)||query|| - -h3. queue - -Get the current job queue. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|order|string||query|| -|filters|array||query|| - -This method is equivalent to the "list method":#list, except that the results are restricted to queued jobs (i.e., jobs that have not yet been started or cancelled) and order defaults to queue priority. - -h3. update - -Update attributes of an existing Job. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Job in question.|path|| -|job|object||query|| diff --git a/doc/api/methods/keep_disks.html.textile.liquid b/doc/api/methods/keep_disks.html.textile.liquid deleted file mode 100644 index 9a82a3e7ce..0000000000 --- a/doc/api/methods/keep_disks.html.textile.liquid +++ /dev/null @@ -1,111 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "keep_disks" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "keep services.":keep_services.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/keep_disks@ - -Object type: @penuu@ - -Example UUID: @zzzzz-penuu-0123456789abcde@ - -h2. Resource - -Obsoleted by "keep_services":{{site.baseurl}}/api/methods/keep_services.html - -Each KeepDisk has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|ping_secret|string||| -|node_uuid|string||| -|filesystem_uuid|string||| -|bytes_total|integer||| -|bytes_free|integer||| -|is_readable|boolean||| -|is_writable|boolean||| -|last_read_at|datetime||| -|last_write_at|datetime||| -|last_ping_at|datetime||| -|keep_service_uuid|string||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new KeepDisk. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|keep_disk|object||query|| - -h3. delete - -Delete an existing KeepDisk. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the KeepDisk in question.|path|| - -h3. get - -Gets a KeepDisk's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the KeepDisk in question.|path|| - -h3. list - -List keep_disks. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. ping - -ping keep_disks - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|ping_secret|string||query|| -{background:#ccffcc}.|service_port|string||query|| -{background:#ccffcc}.|service_ssl_flag|string||query|| -|filesystem_uuid|string||query|| -|node_uuid|string||query|| -|service_host|string||query|| -|uuid|string||query|| - -h3. update - -Update attributes of an existing KeepDisk. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the KeepDisk in question.|path|| -|keep_disk|object||query|| diff --git a/doc/api/methods/nodes.html.textile.liquid b/doc/api/methods/nodes.html.textile.liquid deleted file mode 100644 index b29527ceeb..0000000000 --- a/doc/api/methods/nodes.html.textile.liquid +++ /dev/null @@ -1,106 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "nodes" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "cloud dispatcher API.":../dispatch.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/nodes@ - -Object type: @7ekkf@ - -Example UUID: @zzzzz-7ekkf-0123456789abcde@ - -h2. Resource - -Node resources list compute nodes on which Crunch may schedule work. - -Each Node has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|slot_number|integer||| -|hostname|string||| -|domain|string||| -|ip_address|string||| -|job_uuid|string|The UUID of the job that this node is assigned to work on. If you do not have permission to read the job, this will be null.|| -|first_ping_at|datetime||| -|last_ping_at|datetime||| -|info|hash|Sensitive information about the node (only visible to admin) such as 'ping_secret' and 'ec2_instance_id'. May be used in queries using "subproperty filters":{{site.baseurl}}/api/methods.html#subpropertyfilters|| -|properties|hash|Public information about the node, such as 'total_cpu_cores', 'total_ram_mb', and 'total_scratch_mb'. May be used in queries using "subproperty filters":{{site.baseurl}}/api/methods.html#subpropertyfilters|| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new Node. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|node|object||query|| - -h3. delete - -Delete an existing Node. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Node in question.|path|| - -h3. get - -Gets a Node's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Node in question.|path|| - -h3. list - -List nodes. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. ping - -Process a ping from a compute node. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|ping_secret|string||query|| -{background:#ccffcc}.|uuid|string||path|| - -h3. update - -Update attributes of an existing Node. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Node in question.|path|| -|node|object||query|| - -To remove a node's job assignment, update the node object's @job_uuid@ to null. diff --git a/doc/api/methods/pipeline_instances.html.textile.liquid b/doc/api/methods/pipeline_instances.html.textile.liquid deleted file mode 100644 index e19dfba02a..0000000000 --- a/doc/api/methods/pipeline_instances.html.textile.liquid +++ /dev/null @@ -1,90 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "pipeline_instances" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "container requests.":container_requests.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/pipeline_instances@ - -Object type: @d1hrv@ - -Example UUID: @zzzzz-d1hrv-0123456789abcde@ - -h2. Resource - -Deprecated. A pipeline instance is a collection of jobs managed by @arvados-run-pipeline-instance@. - -Each PipelineInstance has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|pipeline_template_uuid|string|The "pipeline template":pipeline_templates.html that this instance was created from.|| -|name|string||| -|components|hash||| -|success|boolean||| -|active|boolean||| -|properties|Hash||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new PipelineInstance. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|pipeline_instance|object||query|| - -h3. delete - -Delete an existing PipelineInstance. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineInstance in question.|path|| - -h3. get - -Gets a PipelineInstance's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineInstance in question.|path|| - -h3. list - -List pipeline_instances. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing PipelineInstance. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineInstance in question.|path|| -|pipeline_instance|object||query|| diff --git a/doc/api/methods/pipeline_templates.html.textile.liquid b/doc/api/methods/pipeline_templates.html.textile.liquid deleted file mode 100644 index ddbe8ad389..0000000000 --- a/doc/api/methods/pipeline_templates.html.textile.liquid +++ /dev/null @@ -1,228 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "pipeline_templates" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "registered workflows.":workflows.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/pipeline_templates@ - -Object type: @p5p6p@ - -Example UUID: @zzzzz-p5p6p-0123456789abcde@ - -h2. Resource - -Deprecated. A pipeline template is a collection of jobs that can be instantiated as a pipeline_instance. - -Each PipelineTemplate has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|name|string||| -|components|hash||| - -The pipeline template consists of "name" and "components". - -table(table table-bordered table-condensed). -|_. Attribute |_. Type |_. Accepted values |_. Required|_. Description| -|name |string |any |yes |The human-readable name of the pipeline template.| -|components |object |JSON object containing job submission objects|yes |The component jobs that make up the pipeline, with the component name as the key. | - -h3. Components - -The components field of the pipeline template is a JSON object which describes the individual steps that make up the pipeline. Each component is an Arvados job submission. "Parameters for job submissions are described on the job method page.":{{site.baseurl}}/api/methods/jobs.html#create In addition, a component can have the following parameters: - -table(table table-bordered table-condensed). -|_. Attribute |_. Type |_. Accepted values |_. Required|_. Description| -|output_name |string or boolean|string or false |no |If a string is provided, use this name for the output collection of this component. If the value is false, do not create a permanent output collection (an temporary intermediate collection will still be created). If not provided, a default name will be assigned to the output.| - -h3. Script parameters - -When used in a pipeline, each parameter in the 'script_parameters' attribute of a component job can specify that the input parameter must be supplied by the user, or the input parameter should be linked to the output of another component. To do this, the value of the parameter should be JSON object containing one of the following attributes: - -table(table table-bordered table-condensed). -|_. Attribute |_. Type |_. Accepted values |_. Description| -|default |any |any |The default value for this parameter.| -|required |boolean |true or false |Specifies whether the parameter is required to have a value or not.| -|dataclass |string |One of 'Collection', 'File' [1], 'number', or 'text' |Data type of this parameter.| -|search_for |string |any string |Substring to use as a default search string when choosing inputs.| -|output_of |string |the name of another component in the pipeline |Specifies that the value of this parameter should be set to the 'output' attribute of the job that corresponds to the specified component.| -|title |string |any string |User friendly title to display when choosing parameter values| -|description |string |any string |Extended text description for describing expected/valid values for the script parameter| -|link_name |string |any string |User friendly name to display for the parameter value instead of the actual parameter value| - -The 'output_of' parameter is especially important, as this is how components are actually linked together to form a pipeline. Component jobs that depend on the output of other components do not run until the parent job completes and has produced output. If the parent job fails, the entire pipeline fails. - -fn1. The 'File' type refers to a specific file within a Keep collection in the form 'collection_hash/filename', for example '887cd41e9c613463eab2f0d885c6dd96+83/bob.txt'. - -The 'search_for' parameter is meaningful only when input dataclass of type Collection or File is used. If a value is provided, this will be preloaded into the input data chooser dialog in Workbench. For example, if your input dataclass is a File and you are interested in a certain filename extention, you can preconfigure it in this attribute. - -h3. Examples - -This is a pipeline named "Filter MD5 hash values" with two components, "do_hash" and "filter". The "input" script parameter of the "do_hash" component is required to be filled in by the user, and the expected data type is "Collection". This also specifies that the "input" script parameter of the "filter" component is the output of "do_hash", so "filter" will not run until "do_hash" completes successfully. When the pipeline runs, past jobs that meet the criteria described above may be substituted for either or both components to avoid redundant computation. - -
-{
-  "name": "Filter MD5 hash values",
-  "components": {
-    "do_hash": {
-      "script": "hash.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": {
-        "input": {
-          "required": true,
-          "dataclass": "Collection",
-          "search_for": ".fastq.gz",
-          "title":"Please select a fastq file"
-        }
-      },
-    },
-    "filter": {
-      "script": "0-filter.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": {
-        "input": {
-          "output_of": "do_hash"
-        }
-      },
-    }
-  }
-}
-
- -This pipeline consists of three components. The components "thing1" and "thing2" both depend on "cat_in_the_hat". Once the "cat_in_the_hat" job is complete, both "thing1" and "thing2" can run in parallel, because they do not depend on each other. - -
-{
-  "name": "Wreck the house",
-  "components": {
-    "cat_in_the_hat": {
-      "script": "cat.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": { }
-    },
-    "thing1": {
-      "script": "thing1.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": {
-        "input": {
-          "output_of": "cat_in_the_hat"
-        }
-      },
-    },
-    "thing2": {
-      "script": "thing2.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": {
-        "input": {
-          "output_of": "cat_in_the_hat"
-        }
-      },
-    },
-  }
-}
-
- -This pipeline consists of three components. The component "cleanup" depends on "thing1" and "thing2". Both "thing1" and "thing2" are started immediately and can run in parallel, because they do not depend on each other, but "cleanup" cannot begin until both "thing1" and "thing2" have completed. - -
-{
-  "name": "Clean the house",
-  "components": {
-    "thing1": {
-      "script": "thing1.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": { }
-    },
-    "thing2": {
-      "script": "thing2.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": { }
-    },
-    "cleanup": {
-      "script": "cleanup.py",
-      "repository": "you/you",
-      "script_version": "main",
-      "script_parameters": {
-        "mess1": {
-          "output_of": "thing1"
-        },
-        "mess2": {
-          "output_of": "thing2"
-        }
-      }
-    }
-  }
-}
-
- -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new PipelineTemplate. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|pipeline_template|object||query|| - -h3. delete - -Delete an existing PipelineTemplate. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineTemplate in question.|path|| - -h3. get - -Gets a PipelineTemplate's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineTemplate in question.|path|| - -h3. list - -List pipeline_templates. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing PipelineTemplate. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the PipelineTemplate in question.|path|| -|pipeline_template|object||query|| diff --git a/doc/api/methods/repositories.html.textile.liquid b/doc/api/methods/repositories.html.textile.liquid deleted file mode 100644 index b2b2cab7d5..0000000000 --- a/doc/api/methods/repositories.html.textile.liquid +++ /dev/null @@ -1,98 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "repositories" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and slated to be removed entirely in a future major release of Arvados. It is replaced by "collection versioning.":collections.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/repositories@ - -Object type: @s0uqq@ - -Example UUID: @zzzzz-s0uqq-0123456789abcde@ - -h2. Resource - -The repositories resource lists git repositories managed by Arvados. - -Each Repository has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|name|string|The name of the repository on disk. Repository names must begin with a letter and contain only alphanumerics. Unless the repository is owned by the system user, the name must begin with the owner's username, then be separated from the base repository name with @/@. You may not create a repository that is owned by a user without a username.|@username/project1@| -|clone_urls|array|URLs from which the repository can be cloned. Read-only.|@["git@git.zzzzz.arvadosapi.com:foo/bar.git", - "https://git.zzzzz.arvadosapi.com/foo/bar.git"]@| -|fetch_url|string|URL suggested as a fetch-url in git config. Deprecated. Read-only.|| -|push_url|string|URL suggested as a push-url in git config. Deprecated. Read-only.|| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new Repository. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|repository|object||query|| - -h3. delete - -Delete an existing Repository. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Repository in question.|path|| - -h3. get - -Gets a Repository's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Repository in question.|path|| - -h3. get_all_permissions - -get_all_permissions repositories - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | - -h3. list - -List repositories. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing Repository. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Repository in question.|path|| -|repository|object||query|| diff --git a/doc/api/methods/specimens.html.textile.liquid b/doc/api/methods/specimens.html.textile.liquid deleted file mode 100644 index 3820eeb242..0000000000 --- a/doc/api/methods/specimens.html.textile.liquid +++ /dev/null @@ -1,85 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "specimens" -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and is slated to be removed entirely in a future major release of Arvados. The recommended way to store metadata is with "'properties' field on collections and projects.":../properties.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/specimens@ - -Object type: @j58dm@ - -Example UUID: @zzzzz-j58dm-0123456789abcde@ - -h2. Resource - -A metadata record that may be used to represent a biological specimen. - -Each Specimen has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|material|string||| -|properties|hash||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new Specimen. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|specimen|object||query|| - -h3. delete - -Delete an existing Specimen. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Specimen in question.|path|| - -h3. get - -Gets a Specimen's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Specimen in question.|path|| - -h3. list - -List specimens. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing Specimen. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Specimen in question.|path|| -|specimen|object||query|| diff --git a/doc/api/methods/traits.html.textile.liquid b/doc/api/methods/traits.html.textile.liquid deleted file mode 100644 index 4e356b9523..0000000000 --- a/doc/api/methods/traits.html.textile.liquid +++ /dev/null @@ -1,86 +0,0 @@ ---- -layout: default -navsection: api -navmenu: API Methods -title: "traits" - -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -{% include 'notebox_begin_warning' %} -This is a legacy API. This endpoint is deprecated, disabled by default in new installations, and is slated to be removed entirely in a future major release of Arvados. The recommended way to store metadata is with "'properties' field on collections and projects.":../properties.html -{% include 'notebox_end' %} - -API endpoint base: @https://{{ site.arvados_api_host }}/arvados/v1/traits@ - -Object type: @q1cn2@ - -Example UUID: @zzzzz-q1cn2-0123456789abcde@ - -h2. Resource - -A metadata record that may be used to represent a genotype or phenotype trait. - -Each Trait has, in addition to the "Common resource fields":{{site.baseurl}}/api/resources.html: - -table(table table-bordered table-condensed). -|_. Attribute|_. Type|_. Description|_. Example| -|name|string||| -|properties|hash||| - -h2. Methods - -See "Common resource methods":{{site.baseurl}}/api/methods.html for more information about @create@, @delete@, @get@, @list@, and @update@. - -Required arguments are displayed in %{background:#ccffcc}green%. - -h3. create - -Create a new Trait. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -|trait|object||query|| - -h3. delete - -Delete an existing Trait. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Trait in question.|path|| - -h3. get - -Gets a Trait's metadata by UUID. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Trait in question.|path|| - -h3. list - -List traits. - -See "common resource list method.":{{site.baseurl}}/api/methods.html#index - -h3. update - -Update attributes of an existing Trait. - -Arguments: - -table(table table-bordered table-condensed). -|_. Argument |_. Type |_. Description |_. Location |_. Example | -{background:#ccffcc}.|uuid|string|The UUID of the Trait in question.|path|| -|trait|object||query|| diff --git a/doc/architecture/index.html.textile.liquid b/doc/architecture/index.html.textile.liquid index f5405c16e1..230a9be8f5 100644 --- a/doc/architecture/index.html.textile.liquid +++ b/doc/architecture/index.html.textile.liquid @@ -19,7 +19,6 @@ Located in @arvados/services@. table(table table-bordered table-condensed). |_. Component|_. Description| |api|The API server is the core of Arvados. It is backed by a Postgres database and manages information such as metadata for storage, a record of submitted compute jobs, users, groups, and associated permissions.| -|arvados-git-httpd|Provides a git+http interface to Arvados-managed git repositories, with permissions and authentication based on an Arvados API token.| |arvados-dispatch-cloud|Provide elastic computing by creating and destroying cloud based virtual machines on compute demand.| |crunch-dispatch-local|Get compute requests submitted to the API server and execute them locally.| |crunch-dispatch-slurm|Get compute requests submitted to the API server and submit them to slurm.| diff --git a/doc/images/add-new-repository.png b/doc/images/add-new-repository.png deleted file mode 100644 index d62a9869a2..0000000000 Binary files a/doc/images/add-new-repository.png and /dev/null differ diff --git a/doc/install/arvbox.html.textile.liquid b/doc/install/arvbox.html.textile.liquid index 20e1c48eee..7265e2d5cc 100644 --- a/doc/install/arvbox.html.textile.liquid +++ b/doc/install/arvbox.html.textile.liquid @@ -28,7 +28,7 @@ $ ./arvbox start localdemo Arvados-in-a-box starting -Waiting for workbench2 websockets workbench webshell keep-web controller keepproxy api keepstore1 arv-git-httpd keepstore0 sdk vm ... +Waiting for workbench2 websockets workbench webshell keep-web controller keepproxy api keepstore1 keepstore0 sdk vm ... ... diff --git a/doc/install/install-api-server.html.textile.liquid b/doc/install/install-api-server.html.textile.liquid index 06f94a8a5f..95cfca8e6d 100644 --- a/doc/install/install-api-server.html.textile.liquid +++ b/doc/install/install-api-server.html.textile.liquid @@ -30,7 +30,7 @@ h2(#dependencies). Install dependencies # "Install PostgreSQL":install-postgresql.html # "Install Ruby and Bundler":ruby.html # "Install nginx":nginx.html -# "Install Phusion Passenger":https://www.phusionpassenger.com/library/walkthroughs/deploy/ruby/ownserver/nginx/oss/install_passenger_main.html +# "Install Phusion Passenger":https://www.phusionpassenger.com/docs/tutorials/deploy_to_production/installations/oss/ownserver/ruby/nginx/ h2(#database-setup). Set up database @@ -178,10 +178,7 @@ server { index index.html index.htm index.php; passenger_enabled on; - - # If you are using RVM, uncomment the line below. - # If you're using system ruby, leave it commented out. - #passenger_ruby /usr/local/rvm/wrappers/default/ruby; + passenger_preload_bundler on; # This value effectively limits the size of API objects users can # create, especially collections. If you change this, you should diff --git a/doc/install/install-arv-git-httpd.html.textile.liquid b/doc/install/install-arv-git-httpd.html.textile.liquid deleted file mode 100644 index 476c89005f..0000000000 --- a/doc/install/install-arv-git-httpd.html.textile.liquid +++ /dev/null @@ -1,298 +0,0 @@ ---- -layout: default -navsection: installguide -title: Install the Git server -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -# "Introduction":#introduction -# "Install dependencies":#dependencies -# "Create "git" user and storage directory":#create -# "Install gitolite":#gitolite -# "Configure gitolite":#config-gitolite -# "Configure git synchronization":#sync -# "Update config.yml":#update-config -# "Update nginx configuration":#update-nginx -# "Install arvados-git-httpd package":#install-packages -# "Restart the API server and controller":#restart-api -# "Confirm working installation":#confirm-working - -h2(#introduction). Introduction - -Arvados support for git repository management enables using Arvados permissions to control access to git repositories. Users can create their own private and public git repositories and share them with others. - -The git hosting setup involves three components. -* The "arvados-git-sync.rb" script polls the API server for the current list of repositories, creates bare repositories, and updates the local permission cache used by gitolite. -* Gitolite provides SSH access. Users authenticate by SSH keys. -* arvados-git-http provides HTTPS access. Users authenticate by Arvados tokens. - -Git services must be installed on the same host as the Arvados Rails API server. - -h2(#dependencies). Install dependencies - -h3. Alma/CentOS/Red Hat/Rocky - - -
# dnf install git perl-Data-Dumper openssh-server
-
-
- -h3. Debian and Ubuntu - - -
# apt-get --no-install-recommends install git openssh-server
-
-
- -h2(#create). Create "git" user and storage directory - -Gitolite and some additional scripts will be installed in @/var/lib/arvados/git@, which means hosted repository data will be stored in @/var/lib/arvados/git/repositories@. If you choose to install gitolite in a different location, make sure to update the @git_repositories_dir@ entry in your API server's @application.yml@ file accordingly: for example, if you install gitolite at @/data/gitolite@ then your @git_repositories_dir@ will be @/data/gitolite/repositories@. - -A new UNIX account called "git" will own the files. This makes git URLs look familiar to users (git@[...]:username/reponame.git). - -On Debian- or Red Hat-based systems: - - -
gitserver:~$ sudo mkdir -p /var/lib/arvados/git
-gitserver:~$ sudo useradd --comment git --home-dir /var/lib/arvados/git git
-gitserver:~$ sudo chown -R git:git ~git
-
-
- -The git user needs its own SSH key. (It must be able to run ssh git@localhost from scripts.) - - -
gitserver:~$ sudo -u git -i bash
-git@gitserver:~$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
-git@gitserver:~$ cp .ssh/id_rsa.pub .ssh/authorized_keys
-git@gitserver:~$ ssh -o stricthostkeychecking=no localhost cat .ssh/id_rsa.pub
-Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
-ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7aBIDAAgMQN16Pg6eHmvc+D+6TljwCGr4YGUBphSdVb25UyBCeAEgzqRiqy0IjQR2BLtSirXr+1SJAcQfBgI/jwR7FG+YIzJ4ND9JFEfcpq20FvWnMMQ6XD3y3xrZ1/h/RdBNwy4QCqjiXuxDpDB7VNP9/oeAzoATPZGhqjPfNS+RRVEQpC6BzZdsR+S838E53URguBOf9yrPwdHvosZn7VC0akeWQerHqaBIpSfDMtaM4+9s1Gdsz0iP85rtj/6U/K/XOuv2CZsuVZZ52nu3soHnEX2nx2IaXMS3L8Z+lfOXB2T6EaJgXF7Z9ME5K1tx9TSNTRcYCiKztXLNLSbp git@gitserver
-git@gitserver:~$ rm .ssh/authorized_keys
-
-
- -h2(#gitolite). Install gitolite - -Check "https://github.com/sitaramc/gitolite/tags":https://github.com/sitaramc/gitolite/tags for the latest stable version. This guide was tested with @v3.6.11@. _Versions below 3.0 are missing some features needed by Arvados, and should not be used._ - -Download and install the version you selected. - - -
$ sudo -u git -i bash
-git@gitserver:~$ echo 'PATH=$HOME/bin:$PATH' >.profile
-git@gitserver:~$ . .profile
-git@gitserver:~$ git clone --branch v3.6.11 https://github.com/sitaramc/gitolite
-...
-Note: checking out '5d24ae666bfd2fa9093d67c840eb8d686992083f'.
-...
-git@gitserver:~$ mkdir bin
-git@gitserver:~$ gitolite/install -ln ~git/bin
-git@gitserver:~$ bin/gitolite setup -pk .ssh/id_rsa.pub
-Initialized empty Git repository in /var/lib/arvados/git/repositories/gitolite-admin.git/
-Initialized empty Git repository in /var/lib/arvados/git/repositories/testing.git/
-WARNING: /var/lib/arvados/git/.ssh/authorized_keys missing; creating a new one
-    (this is normal on a brand new install)
-
-
- -_If this didn't go well, more detail about installing gitolite, and information about how it works, can be found on the "gitolite home page":http://gitolite.com/._ - -Clone the gitolite-admin repository. The arvados-git-sync.rb script works by editing the files in this working directory and pushing them to gitolite. Here we make sure "git push" won't produce any errors or warnings. - - -
git@gitserver:~$ git clone git@localhost:gitolite-admin
-Cloning into 'gitolite-admin'...
-remote: Counting objects: 6, done.
-remote: Compressing objects: 100% (4/4), done.
-remote: Total 6 (delta 0), reused 0 (delta 0)
-Receiving objects: 100% (6/6), done.
-Checking connectivity... done.
-git@gitserver:~$ cd gitolite-admin
-git@gitserver:~/gitolite-admin$ git config user.email arvados
-git@gitserver:~/gitolite-admin$ git config user.name arvados
-git@gitserver:~/gitolite-admin$ git config push.default simple
-git@gitserver:~/gitolite-admin$ git push
-Everything up-to-date
-
-
- -h2(#config-gitolite). Configure gitolite - -Configure gitolite to look up a repository name like @username/reponame.git@ and find the appropriate bare repository storage directory. - -Add the following lines to the top of @~git/.gitolite.rc@: - - -
my $repo_aliases;
-my $aliases_src = "$ENV{HOME}/.gitolite/arvadosaliases.pl";
-if ($ENV{HOME} && (-e $aliases_src)) {
-    $repo_aliases = do $aliases_src;
-}
-$repo_aliases ||= {};
-
-
- -Add the following lines inside the section that begins @%RC = (@: - - -
    REPO_ALIASES => $repo_aliases,
-
-
- -Inside that section, adjust the 'UMASK' setting to @022@, to ensure the API server has permission to read repositories: - - -
    UMASK => 022,
-
-
- -Uncomment the 'Alias' line in the section that begins @ENABLE => [@: - - -
            # access a repo by another (possibly legacy) name
-            'Alias',
-
-
- -h2(#sync). Configure git synchronization - -Create a configuration file @/var/www/arvados-api/current/config/arvados-clients.yml@ using the following template, filling in the appropriate values for your system. -* For @arvados_api_token@, use @SystemRootToken@ -* For @gitolite_arvados_git_user_key@, provide the public key you generated above, i.e., the contents of @~git/.ssh/id_rsa.pub@. - - -
production:
-  gitolite_url: /var/lib/arvados/git/repositories/gitolite-admin.git
-  gitolite_tmp: /var/lib/arvados/git
-  arvados_api_host: ClusterID.example.com
-  arvados_api_token: "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
-  arvados_api_host_insecure: false
-  gitolite_arvados_git_user_key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7aBIDAAgMQN16Pg6eHmvc+D+6TljwCGr4YGUBphSdVb25UyBCeAEgzqRiqy0IjQR2BLtSirXr+1SJAcQfBgI/jwR7FG+YIzJ4ND9JFEfcpq20FvWnMMQ6XD3y3xrZ1/h/RdBNwy4QCqjiXuxDpDB7VNP9/oeAzoATPZGhqjPfNS+RRVEQpC6BzZdsR+S838E53URguBOf9yrPwdHvosZn7VC0akeWQerHqaBIpSfDMtaM4+9s1Gdsz0iP85rtj/6U/K/XOuv2CZsuVZZ52nu3soHnEX2nx2IaXMS3L8Z+lfOXB2T6EaJgXF7Z9ME5K1tx9TSNTRcYCiKztXLNLSbp git@gitserver"
-
-
- -
-$ sudo chown git:git /var/www/arvados-api/current/config/arvados-clients.yml
-$ sudo chmod og-rwx /var/www/arvados-api/current/config/arvados-clients.yml
-
- -h3. Test configuration - -notextile.
$ sudo -u git -i bash -c 'cd /var/www/arvados-api/current && bin/bundle exec script/arvados-git-sync.rb production'
- -h3. Enable the synchronization script - -The API server package includes a script that retrieves the current set of repository names and permissions from the API, writes them to @arvadosaliases.pl@ in a format usable by gitolite, and triggers gitolite hooks which create new empty repositories if needed. This script should run every 2 to 5 minutes. - -Create @/etc/cron.d/arvados-git-sync@ with the following content: - - -
*/5 * * * * git cd /var/www/arvados-api/current && bin/bundle exec script/arvados-git-sync.rb production
-
-
- -h2(#update-config). Update config.yml - -Edit the cluster config at @config.yml@ . - - -
    Services:
-      GitSSH:
-        ExternalURL: "ssh://git@git.ClusterID.example.com"
-      GitHTTP:
-        ExternalURL: https://git.ClusterID.example.com/
-        InternalURLs:
-	  "http://localhost:9001": {}
-    Git:
-      GitCommand: /var/lib/arvados/git/gitolite/src/gitolite-shell
-      GitoliteHome: /var/lib/arvados/git
-      Repositories: /var/lib/arvados/git/repositories
-
-
- -h2(#update-nginx). Update nginx configuration - -Use a text editor to create a new file @/etc/nginx/conf.d/arvados-git.conf@ with the following configuration. Options that need attention are marked in red. - - -
upstream arvados-git-httpd {
-  server                  127.0.0.1:9001;
-}
-server {
-  listen                  443 ssl;
-  server_name             git.ClusterID.example.com;
-  proxy_connect_timeout   90s;
-  proxy_read_timeout      300s;
-
-  ssl_certificate         /YOUR/PATH/TO/cert.pem;
-  ssl_certificate_key     /YOUR/PATH/TO/cert.key;
-
-  # The server needs to accept potentially large refpacks from push clients.
-  client_max_body_size 128m;
-
-  location  / {
-    proxy_pass            http://arvados-git-httpd;
-  }
-}
-
-
- -h2(#install-packages). Install the arvados-git-httpd package - -The arvados-git-httpd package provides HTTP access, using Arvados authentication tokens instead of passwords. It must be installed on the system where your git repositories are stored. - -h3. Alma/CentOS/Red Hat/Rocky - - -
# dnf install arvados-git-httpd
-
-
- -h3. Debian and Ubuntu - - -
# apt-get --no-install-recommends install arvados-git-httpd
-
-
- -h2(#restart-api). Restart the API server and controller - -After adding Workbench to the Services section, make sure the cluster config file is up to date on the API server host, and restart the API server and controller processes to ensure the changes are applied. - - -
# systemctl restart nginx arvados-controller
-
-
- -h2(#confirm-working). Confirm working installation - -Create 'testrepo' in the Arvados database. - - -
~$ arv --format=uuid repository create --repository '{"name":"myusername/testrepo"}'
-
- -The arvados-git-sync cron job will notice the new repository record and create a repository on disk. Because it is on a timer (default 5 minutes) you may have to wait a minute or two for it to show up. - -h3. SSH - -Before you do this, go to Workbench and choose *SSH Keys* from the menu, and upload your public key. Arvados uses the public key to identify you when you access the git repo. - - -
~$ git clone git@git.ClusterID.example.com:username/testrepo.git
-
-
- -h3. HTTP - -Set up git credential helpers as described in "install shell server":install-shell-server.html#config-git for the git command to use your API token instead of prompting you for a username and password. - - -
~$ git clone https://git.ClusterID.example.com/username/testrepo.git
-
-
diff --git a/doc/install/install-composer.html.textile.liquid b/doc/install/install-composer.html.textile.liquid deleted file mode 100644 index 58ba5d03a0..0000000000 --- a/doc/install/install-composer.html.textile.liquid +++ /dev/null @@ -1,65 +0,0 @@ ---- -layout: default -navsection: installguide -title: Install Composer -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -Arvados Composer is a web-based javascript application for building Common Workflow Languge (CWL) Workflows. - -# "Install dependencies":#dependencies -# "Update config.yml":#update-config -# "Update Nginx configuration":#update-nginx -# "Install arvados-composer":#install-packages -# "Restart the API server and controller":#restart-api -# "Confirm working installation":#confirm-working - -h2(#dependencies). Install dependencies - -In addition to Arvados core services, Composer requires "Arvados hosted git repositories":install-arv-git-httpd.html which are used for storing workflow files. - -h2(#configure). Update config.yml - -Edit @config.yml@ and set @Services.Composer.ExternalURL@ to the location from which it is served: - - -
    Services:
-      Composer:
-        ExternalURL: https://workbench.CusterID.example.com/composer
-
- -h2(#update-nginx). Update nginx configuration - -Composer may be served from the same host as Workbench. Composer communicates directly with the Arvados API server. It does not require its own backend and should be served as a static file. - -Add the following @location@ sections to @/etc/nginx/conf.d/arvados-workbench.conf@ . - - -
server {
-  [...]
-
-  location /composer {
-    root   /var/www/arvados-composer;
-    index  index.html;
-  }
-
-  location /composer/composer.yml {
-    return 200 '{ "API_HOST": "ClusterID.example.com" }';
-  }
-}
-
-
- -{% assign arvados_component = 'arvados-composer' %} - -{% include 'install_packages' %} - -{% include 'restart_api' %} - -h2(#confirm-working). Confirm working installation - -Visit @https://workbench.ClusterID.example.com/composer@ in a browser. You should be able to log in using the login method you configured previously. diff --git a/doc/install/install-jobs-image.html.textile.liquid b/doc/install/install-jobs-image.html.textile.liquid deleted file mode 100644 index efd8c9649f..0000000000 --- a/doc/install/install-jobs-image.html.textile.liquid +++ /dev/null @@ -1,38 +0,0 @@ ---- -layout: default -navsection: installguide -title: Install arvados/jobs image -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -h2. Create a project for Docker images - -Here we create a default project for the standard Arvados Docker images, and give all users read access to it. The project is owned by the system user. - - -
~$ uuid_prefix=$(arv --format=uuid user current | cut -d- -f1)
-~$ project_uuid=$(arv --format=uuid group create --group '{"owner_uuid":"'$uuid_prefix'-tpzed-000000000000000", "group_class":"project", "name":"Arvados Standard Docker Images"}')
-~$ echo "Arvados project uuid is '$project_uuid'"
-~$ read -rd $'\000' newlink <<EOF; arv link create --link "$newlink"
-{
- "tail_uuid":"${uuid_prefix}-j7d0g-fffffffffffffff",
- "head_uuid":"$project_uuid",
- "link_class":"permission",
- "name":"can_read"
-}
-EOF
-
- -h2. Import the arvados/jobs docker image - -In order to start workflows from workbench, there needs to be Docker image @arvados/jobs@ tagged with the version of Arvados you are installing. The following command downloads the latest arvados/jobs image from Docker Hub, loads it into Keep. In this example @$project_uuid@ should be the UUID of the "Arvados Standard Docker Images" project. - - -
~$ arv-keepdocker --pull arvados/jobs latest --project-uuid $project_uuid
-
- -If the image needs to be downloaded from Docker Hub, the command can take a few minutes to complete, depending on available network bandwidth. diff --git a/doc/install/install-manual-prerequisites.html.textile.liquid b/doc/install/install-manual-prerequisites.html.textile.liquid index 8819b0210f..ba179f82dd 100644 --- a/doc/install/install-manual-prerequisites.html.textile.liquid +++ b/doc/install/install-manual-prerequisites.html.textile.liquid @@ -47,7 +47,6 @@ table(table table-bordered table-condensed). |\3=. *Additional services*| |"Websockets server":install-ws.html |Event distribution server.|Required to view streaming container logs in Workbench.| |"Shell server":install-shell-server.html |Grant Arvados users access to Unix shell accounts on dedicated shell nodes.|Optional.| -|"Git server":install-arv-git-httpd.html |Arvados-hosted git repositories, with Arvados-token based authentication.|Optional| |\3=. *Crunch (running containers)*| |"arvados-dispatch-cloud":crunch2-cloud/install-dispatch-cloud.html |Run analysis workflows on cloud by allocating and freeing cloud VM instances on demand.|Optional| |"crunch-dispatch-slurm":crunch2-slurm/install-dispatch.html |Run analysis workflows distributed across a Slurm cluster.|Optional| @@ -96,7 +95,7 @@ For a production installation, this is a reasonable starting point:
table(table table-bordered table-condensed). |_. Function|_. Number of nodes|_. Recommended specs| -|PostgreSQL database, Arvados API server, Arvados controller, Git, Websockets, Container dispatcher|1|16+ GiB RAM, 4+ cores, fast disk for database| +|PostgreSQL database, Arvados API server, Arvados controller, Websockets, Container dispatcher|1|16+ GiB RAM, 4+ cores, fast disk for database| |Workbench, Keepproxy, Keep-web, Keep-balance|1|8 GiB RAM, 2+ cores| |Keepstore servers ^1^|2+|4 GiB RAM| |Compute worker nodes ^1^|0+ |Depends on workload; scaled dynamically in the cloud| @@ -138,7 +137,6 @@ It is possible to use custom DNS names for the Arvados services. table(table table-bordered table-condensed). |_. Function|_. DNS name| |Arvados API|@ClusterID.example.com@| -|Arvados Git server|git.@ClusterID.example.com@| |Arvados Webshell|webshell.@ClusterID.example.com@| |Arvados Websockets endpoint|ws.@ClusterID.example.com@| |Arvados Workbench|workbench.@ClusterID.example.com@| diff --git a/doc/install/install-shell-server.html.textile.liquid b/doc/install/install-shell-server.html.textile.liquid index f864f37563..9520c08397 100644 --- a/doc/install/install-shell-server.html.textile.liquid +++ b/doc/install/install-shell-server.html.textile.liquid @@ -12,7 +12,6 @@ SPDX-License-Identifier: CC-BY-SA-3.0 # "Introduction":#introduction # "Install Dependencies and SDKs":#dependencies # "Install git and curl":#install-packages -# "Update Git Config":#config-git # "Create record for VM":#vm-record # "Install arvados-login-sync":#arvados-login-sync # "Confirm working installation":#confirm-working @@ -44,17 +43,6 @@ h2(#dependencies). Install Dependencies and SDKs {% include 'install_packages' %} -h2(#config-git). Update Git Config - -Configure git to use the ARVADOS_API_TOKEN environment variable to authenticate to arvados-git-httpd. We use the @--system@ flag so it takes effect for all current and future user accounts. It does not affect git's behavior when connecting to other git servers. - - -
-# git config --system 'credential.https://git.ClusterID.example.com/.username' none
-# git config --system 'credential.https://git.ClusterID.example.com/.helper' '!cred(){ cat >/dev/null; if [ "$1" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred'
-
-
- h2(#vm-record). Create record for VM As an admin, create an Arvados virtual_machine object representing this shell server. This will return a uuid. diff --git a/doc/install/salt-multi-host.html.textile.liquid b/doc/install/salt-multi-host.html.textile.liquid index a3cdd03300..ddf9e5d797 100644 --- a/doc/install/salt-multi-host.html.textile.liquid +++ b/doc/install/salt-multi-host.html.textile.liquid @@ -392,16 +392,22 @@ This will install and configure Arvados on all the nodes. It will take a while h2(#test-install). Confirm the cluster is working -When everything has finished, you can run the diagnostics. +When everything has finished, you can run the diagnostics. There's a couple ways of doing this listed below. -Depending on where you are running the installer, you need to provide @-internal-client@ or @-external-client@. +h3. Running diagnostics from the same system as the installer -If you are running the diagnostics from one of the Arvados machines inside the private network, you want @-internal-client@ . +The requirements to run diagnostics are having @arvados-client@ and @docker@ installed. If this is not possible you can run them on your Arvados shell node as explained in the next section. -You are an "external client" if you running the diagnostics from your workstation outside of the private network. +Depending on where you are running the installer, you need to provide @-internal-client@ or @-external-client@. If you are running the installer from a host connected to the Arvados private network, use @-internal-client@. Otherwise, use @-external-client@.
./installer.sh diagnostics (-internal-client|-external-client)
+h3. Running diagnostics from a cluster node + +You can run the diagnostics from the cluster's shell node. This has the advantage that you don't need to manage any software on your local system, but might not be a possibility if your Arvados cluster doesn't include a shell node. + +
./installer.sh diagnostics-internal
+ h3(#debugging). Debugging issues The installer records log files for each deployment. diff --git a/doc/sdk/cli/index.html.textile.liquid b/doc/sdk/cli/index.html.textile.liquid index ea10c830bc..827f1d0876 100644 --- a/doc/sdk/cli/index.html.textile.liquid +++ b/doc/sdk/cli/index.html.textile.liquid @@ -31,12 +31,12 @@ Available flags: Use 'arv subcommand|resource --help' to get more information about a particular command or resource. -Available subcommands: copy, create, edit, keep, pipeline, run, tag, ws +Available subcommands: copy, create, edit, keep, run, tag, ws -Available resources: api_client_authorization, api_client, authorized_key, -collection, user_agreement, group, job_task, link, log, keep_disk, -pipeline_instance, node, repository, specimen, pipeline_template, user, -virtual_machine, trait, human, job, keep_service +Available resources: api_client_authorization, api_client, +authorized_key, collection, container, container_request, +user_agreement, group, keep_service, link, log, user, virtual_machine, +workflow Additional options: -e, --version Print version and exit diff --git a/doc/user/tutorials/add-new-repository.html.textile.liquid b/doc/user/tutorials/add-new-repository.html.textile.liquid deleted file mode 100644 index 6046e7d14b..0000000000 --- a/doc/user/tutorials/add-new-repository.html.textile.liquid +++ /dev/null @@ -1,47 +0,0 @@ ---- -layout: default -navsection: userguide -title: Adding a new Arvados git repository -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -Arvados supports managing git repositories. You can access these repositories using your Arvados credentials and share them with other Arvados users. - -{% include 'tutorial_expectations' %} - -h2. Setting up Git - -Before you start using Git and arvados repositories, you should do some basic configuration (you only need to do this the first time): - - -
~$ git config --global user.name "Your Name"
-~$ git config --global user.email $USER@example.com
-
- -h2. Add "tutorial" repository - -On the Arvados Workbench, click on the dropdown menu icon (Account Management) in the upper right corner of the top navigation menu to access the user settings menu, and click on the menu item *Repositories*. - -In the *Repositories* page, you will see the + NEW REPOSITORY button. - -!{width: 100%;}{{ site.baseurl }}/images/repositories-panel.png! - -Click the + NEW REPOSITORY button to open the popup to add a new Arvados repository. You will see a text box where you can enter the name of the repository. Enter *tutorial* in this text box and click on *Create*. - -{% include 'notebox_begin' %} -The name you enter here must begin with a letter and can only contain alphanumeric characters. -{% include 'notebox_end' %} - -!{width: 100%;}{{ site.baseurl }}/images/add-new-repository.png! - -This will create a new repository with the name @$USER/tutorial@. It can be accessed using the URL https://git.{{ site.arvados_api_host }}/$USER/tutorial.git or git@git.{{ site.arvados_api_host }}:$USER/tutorial.git - -Back in the *Repositories* page, you should see the @$USER/tutorial@ repository listed in the name column with these URLs. - -!{display: block;margin-left: 25px;margin-right: auto;}{{ site.baseurl }}/images/added-new-repository.png! - -You are now ready to use this *tutorial* repository to run your crunch scripts. diff --git a/doc/user/tutorials/git-arvados-guide.html.textile.liquid b/doc/user/tutorials/git-arvados-guide.html.textile.liquid deleted file mode 100644 index a4ac2a5795..0000000000 --- a/doc/user/tutorials/git-arvados-guide.html.textile.liquid +++ /dev/null @@ -1,87 +0,0 @@ ---- -layout: default -navsection: userguide -title: Working with an Arvados git repository -... -{% comment %} -Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: CC-BY-SA-3.0 -{% endcomment %} - -This tutorial describes how to work with an Arvados-managed git repository. Working with an Arvados git repository is very similar to working with other public git repositories. - -{% include 'tutorial_expectations' %} - -{% include 'tutorial_git_repo_expectations' %} - -h2. Cloning a git repository - -Before you start using Git, you should do some basic configuration (you only need to do this the first time): - - -
~$ git config --global user.name "Your Name"
-~$ git config --global user.email $USER@example.com
-
- -On the Arvados Workbench, click on the dropdown menu icon in the upper right corner of the top navigation menu to access the Account Management menu, and click on the menu item *Repositories*. In the *Repositories* page, you should see the @$USER/tutorial@ repository listed in the *name* column. Next to *name* is the column *URL*. Copy the *URL* value associated with your repository. This should look like https://git.{{ site.arvados_api_host }}/$USER/tutorial.git. Alternatively, you can use git@git.{{ site.arvados_api_host }}:$USER/tutorial.git - -Next, on the Arvados virtual machine, clone your Git repository: - - -
~$ cd $HOME # (or wherever you want to install)
-~$ git clone https://git.{{ site.arvados_api_host }}/$USER/tutorial.git
-Cloning into 'tutorial'...
-
- -This will create a Git repository in the directory called @tutorial@ in your home directory. Say yes when prompted to continue with connection. -Ignore any warning that you are cloning an empty repository. - -*Note:* If you are prompted for username and password when you try to git clone using this command, you may first need to update your git configuration. Execute the following commands to update your git configuration. - - -
-~$ git config 'credential.https://git.{{ site.arvados_api_host }}/.username' none
-~$ git config 'credential.https://git.{{ site.arvados_api_host }}/.helper' '!cred(){ cat >/dev/null; if [ "$1" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred'
-
-
- -h2. Creating a git branch in an Arvados repository - -Create a git branch named *tutorial_branch* in the *tutorial* Arvados git repository. - - -
~$ cd tutorial
-~/tutorial$ git checkout -b tutorial_branch
-
-
- -h2. Adding scripts to an Arvados repository - -A git repository is a good place to store the CWL workflows that you run on Arvados. - -First, create a simple CWL CommandLineTool: - -notextile.
~/tutorials$ nano hello.cwl
- - {% code tutorial_hello_cwl as yaml %} - -Next, add the file to the git repository. This tells @git@ that the file should be included on the next commit. - -notextile.
~/tutorial$ git add hello.cwl
- -Next, commit your changes. All staged changes are recorded into the local git repository: - - -
~/tutorial$ git commit -m "my first script"
-
-
- -Finally, upload your changes to the remote repository: - - -
~/tutorial/crunch_scripts$ git push origin tutorial_branch
-
-
- -The same steps can be used to add any of your custom bash, R, or python scripts to an Arvados repository. diff --git a/go.mod b/go.mod index aef54ac1c1..aaad05dab2 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/arvados/cgofuse v1.2.0-arvados1 github.com/aws/aws-sdk-go v1.44.174 github.com/aws/aws-sdk-go-v2 v0.23.0 + github.com/bmatcuk/doublestar/v4 v4.6.1 github.com/bradleypeabody/godap v0.0.0-20170216002349-c249933bc092 github.com/coreos/go-oidc/v3 v3.5.0 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e @@ -38,7 +39,7 @@ require ( github.com/prometheus/common v0.39.0 github.com/sirupsen/logrus v1.8.1 golang.org/x/crypto v0.22.0 - golang.org/x/net v0.21.0 + golang.org/x/net v0.24.0 golang.org/x/oauth2 v0.11.0 golang.org/x/sys v0.19.0 google.golang.org/api v0.126.0 diff --git a/go.sum b/go.sum index c5f4d837d3..d585789817 100644 --- a/go.sum +++ b/go.sum @@ -59,6 +59,8 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I= +github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradleypeabody/godap v0.0.0-20170216002349-c249933bc092 h1:0Di2onNnlN5PAyWPbqlPyN45eOQ+QW/J9eqLynt4IV4= github.com/bradleypeabody/godap v0.0.0-20170216002349-c249933bc092/go.mod h1:8IzBjZCRSnsvM6MJMG8HNNtnzMl48H22rbJL2kRUJ0Y= @@ -321,8 +323,8 @@ golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= diff --git a/lib/boot/nginx.go b/lib/boot/nginx.go index 9f1091eac3..338a6b5bcc 100644 --- a/lib/boot/nginx.go +++ b/lib/boot/nginx.go @@ -74,7 +74,6 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er {"KEEPWEB", super.cluster.Services.WebDAV}, {"KEEPWEBDL", super.cluster.Services.WebDAVDownload}, {"KEEPPROXY", super.cluster.Services.Keepproxy}, - {"GIT", super.cluster.Services.GitHTTP}, {"HEALTH", super.cluster.Services.Health}, {"WORKBENCH1", super.cluster.Services.Workbench1}, {"WORKBENCH2", super.cluster.Services.Workbench2}, @@ -135,7 +134,7 @@ func (runNginx) Run(ctx context.Context, fail func(error), super *Supervisor) er } } - configs := "error_log stderr info; " + configs := "error_log stderr warn; " configs += "pid " + filepath.Join(super.wwwtempdir, "nginx.pid") + "; " configs += "user www-data; " diff --git a/lib/boot/passenger.go b/lib/boot/passenger.go index 5367337e81..bf2ca2a78b 100644 --- a/lib/boot/passenger.go +++ b/lib/boot/passenger.go @@ -84,14 +84,9 @@ func (runner installPassenger) Run(ctx context.Context, fail func(error), super if err != nil { return err } - for _, version := range []string{"2.2.19"} { - if !strings.Contains(buf.String(), "("+version+")") { - err = super.RunProgram(ctx, appdir, runOptions{}, "gem", "install", "--user", "--conservative", "--no-document", "bundler:2.2.19") - if err != nil { - return err - } - break - } + err = super.RunProgram(ctx, appdir, runOptions{}, "gem", "install", "--user", "--conservative", "--no-document", "--version", "~> 2.4.0", "bundler") + if err != nil { + return err } err = super.RunProgram(ctx, appdir, runOptions{}, "bundle", "config", "--set", "local", "path", filepath.Join(os.Getenv("HOME"), ".gem")) if err != nil { diff --git a/lib/boot/supervisor.go b/lib/boot/supervisor.go index ac269b933a..67649e75de 100644 --- a/lib/boot/supervisor.go +++ b/lib/boot/supervisor.go @@ -366,7 +366,6 @@ func (super *Supervisor) runCluster() error { runNginx{}, railsDatabase{}, runServiceCommand{name: "controller", svc: super.cluster.Services.Controller, depends: []supervisedTask{railsDatabase{}}}, - runServiceCommand{name: "git-httpd", svc: super.cluster.Services.GitHTTP}, runServiceCommand{name: "health", svc: super.cluster.Services.Health}, runServiceCommand{name: "keepproxy", svc: super.cluster.Services.Keepproxy, depends: []supervisedTask{runPassenger{src: "services/api"}}}, runServiceCommand{name: "keepstore", svc: super.cluster.Services.Keepstore}, @@ -821,7 +820,6 @@ func (super *Supervisor) autofillConfig() error { for _, svc := range []*arvados.Service{ &super.cluster.Services.Controller, &super.cluster.Services.DispatchCloud, - &super.cluster.Services.GitHTTP, &super.cluster.Services.Health, &super.cluster.Services.Keepproxy, &super.cluster.Services.Keepstore, @@ -839,7 +837,6 @@ func (super *Supervisor) autofillConfig() error { } host := net.JoinHostPort(defaultExtHost, port) if svc == &super.cluster.Services.Controller || - svc == &super.cluster.Services.GitHTTP || svc == &super.cluster.Services.Health || svc == &super.cluster.Services.Keepproxy || svc == &super.cluster.Services.WebDAV || diff --git a/lib/config/config.default.yml b/lib/config/config.default.yml index 14e839a6cd..e32c168e2d 100644 --- a/lib/config/config.default.yml +++ b/lib/config/config.default.yml @@ -74,12 +74,6 @@ Clusters: Keepbalance: InternalURLs: {SAMPLE: {ListenURL: ""}} ExternalURL: "" - GitHTTP: - InternalURLs: {SAMPLE: {ListenURL: ""}} - ExternalURL: "" - GitSSH: - InternalURLs: {SAMPLE: {ListenURL: ""}} - ExternalURL: "" DispatchCloud: InternalURLs: {SAMPLE: {ListenURL: ""}} ExternalURL: "" @@ -340,7 +334,6 @@ Clusters: # AutoSetupUsernameBlacklist is a list of usernames to be blacklisted for auto setup. AutoSetupNewUsers: false AutoSetupNewUsersWithVmUUID: "" - AutoSetupNewUsersWithRepository: false AutoSetupUsernameBlacklist: arvados: {} git: {} @@ -758,8 +751,8 @@ Clusters: TTL: 300s # Maximum amount of data cached in /var/cache/arvados/keep. - # Can be given as a percentage ("10%") or a number of bytes - # ("10 GiB") + # Can be given as a percentage of filesystem size ("10%") or a + # number of bytes ("10 GiB") DiskCacheSize: 10% # Approximate memory limit (in bytes) for session cache. @@ -1058,24 +1051,6 @@ Clusters: # production use. TrustPrivateNetworks: false - Git: - # Path to git or gitolite-shell executable. Each authenticated - # request will execute this program with the single argument "http-backend" - GitCommand: /usr/bin/git - - # Path to Gitolite's home directory. If a non-empty path is given, - # the CGI environment will be set up to support the use of - # gitolite-shell as a GitCommand: for example, if GitoliteHome is - # "/gh", then the CGI environment will have GITOLITE_HTTP_HOME=/gh, - # PATH=$PATH:/gh/bin, and GL_BYPASS_ACCESS_CHECKS=1. - GitoliteHome: "" - - # Git repositories must be readable by api server, or you won't be - # able to submit crunch jobs. To pass the test suites, put a clone - # of the arvados tree in {git_repositories_dir}/arvados.git or - # {git_repositories_dir}/arvados/.git - Repositories: /var/lib/arvados/git/repositories - TLS: # Use "file:///var/lib/acme/live/example.com/cert" and # ".../privkey" to load externally managed certificates. @@ -1260,45 +1235,6 @@ Clusters: LocalKeepLogsToContainerLog: none Logging: - # Periodically (see SweepInterval) Arvados will check for - # containers that have been finished for at least this long, - # and delete their stdout, stderr, arv-mount, crunch-run, and - # crunchstat logs from the logs table. - MaxAge: 720h - - # How often to delete cached log entries for finished - # containers (see MaxAge). - SweepInterval: 12h - - # These two settings control how frequently log events are flushed to the - # database. Log lines are buffered until either crunch_log_bytes_per_event - # has been reached or crunch_log_seconds_between_events has elapsed since - # the last flush. - LogBytesPerEvent: 4096 - LogSecondsBetweenEvents: 5s - - # The sample period for throttling logs. - LogThrottlePeriod: 60s - - # Maximum number of bytes that job can log over crunch_log_throttle_period - # before being silenced until the end of the period. - LogThrottleBytes: 65536 - - # Maximum number of lines that job can log over crunch_log_throttle_period - # before being silenced until the end of the period. - LogThrottleLines: 1024 - - # Maximum bytes that may be logged as legacy log events - # (records posted to the "logs" table). Starting with Arvados - # 2.7, container live logging has migrated to a new system - # (polling the container request live log endpoint) and this - # value should be 0. As of this writing, the container will - # still create a single log on the API server, noting for that - # log events are throttled. - LimitLogBytesPerJob: 0 - - LogPartialLineThrottlePeriod: 5s - # Container logs are written to Keep and saved in a # collection, which is updated periodically while the # container runs. This value sets the interval between @@ -1335,47 +1271,6 @@ Clusters: SbatchArgumentsList: [] SbatchEnvironmentVariables: SAMPLE: "" - Managed: - # Path to dns server configuration directory - # (e.g. /etc/unbound.d/conf.d). If false, do not write any config - # files or touch restart.txt (see below). - DNSServerConfDir: "" - - # Template file for the dns server host snippets. See - # unbound.template in this directory for an example. If false, do - # not write any config files. - DNSServerConfTemplate: "" - - # String to write to {dns_server_conf_dir}/restart.txt (with a - # trailing newline) after updating local data. If false, do not - # open or write the restart.txt file. - DNSServerReloadCommand: "" - - # Command to run after each DNS update. Template variables will be - # substituted; see the "unbound" example below. If false, do not run - # a command. - DNSServerUpdateCommand: "" - - ComputeNodeDomain: "" - ComputeNodeNameservers: - "192.168.1.1": {} - SAMPLE: {} - - # Hostname to assign to a compute node when it sends a "ping" and the - # hostname in its Node record is nil. - # During bootstrapping, the "ping" script is expected to notice the - # hostname given in the ping response, and update its unix hostname - # accordingly. - # If false, leave the hostname alone (this is appropriate if your compute - # nodes' hostnames are already assigned by some other mechanism). - # - # One way or another, the hostnames of your node records should agree - # with your DNS records and your /etc/slurm-llnl/slurm.conf files. - # - # Example for compute0000, compute0001, ....: - # assign_node_hostname: compute%04d - # (See http://ruby-doc.org/core-2.2.2/Kernel.html#method-i-format for more.) - AssignNodeHostname: "compute%d" LSF: # Arguments to bsub when submitting Arvados containers as LSF jobs. @@ -1443,12 +1338,6 @@ Clusters: # 'false' -- disable the Jobs API despite presence of existing records. Enable: 'auto' - # Git repositories must be readable by api server, or you won't be - # able to submit crunch jobs. To pass the test suites, put a clone - # of the arvados tree in {git_repositories_dir}/arvados.git or - # {git_repositories_dir}/arvados/.git - GitInternalDir: /var/lib/arvados/internal.git - CloudVMs: # Enable the cloud scheduler. Enable: false diff --git a/lib/config/deprecated.go b/lib/config/deprecated.go index d518b3414a..0db3de7fc9 100644 --- a/lib/config/deprecated.go +++ b/lib/config/deprecated.go @@ -510,56 +510,6 @@ func (ldr *Loader) loadOldKeepWebConfig(cfg *arvados.Config) error { return nil } -const defaultGitHttpdConfigPath = "/etc/arvados/git-httpd/git-httpd.yml" - -type oldGitHttpdConfig struct { - Client *arvados.Client - Listen *string - GitCommand *string - GitoliteHome *string - RepoRoot *string - ManagementToken *string -} - -func (ldr *Loader) loadOldGitHttpdConfig(cfg *arvados.Config) error { - if ldr.GitHttpdPath == "" { - return nil - } - var oc oldGitHttpdConfig - err := ldr.loadOldConfigHelper("arvados-git-httpd", ldr.GitHttpdPath, &oc) - if os.IsNotExist(err) && ldr.GitHttpdPath == defaultGitHttpdConfigPath { - return nil - } else if err != nil { - return err - } - - cluster, err := cfg.GetCluster("") - if err != nil { - return err - } - - loadOldClientConfig(cluster, oc.Client) - - if oc.Listen != nil { - cluster.Services.GitHTTP.InternalURLs[arvados.URL{Host: *oc.Listen}] = arvados.ServiceInstance{} - } - if oc.ManagementToken != nil { - cluster.ManagementToken = *oc.ManagementToken - } - if oc.GitCommand != nil { - cluster.Git.GitCommand = *oc.GitCommand - } - if oc.GitoliteHome != nil { - cluster.Git.GitoliteHome = *oc.GitoliteHome - } - if oc.RepoRoot != nil { - cluster.Git.Repositories = *oc.RepoRoot - } - - cfg.Clusters[cluster.ClusterID] = *cluster - return nil -} - const defaultKeepBalanceConfigPath = "/etc/arvados/keep-balance/keep-balance.yml" type oldKeepBalanceConfig struct { diff --git a/lib/config/deprecated_test.go b/lib/config/deprecated_test.go index e06a1f231d..f73a92be5c 100644 --- a/lib/config/deprecated_test.go +++ b/lib/config/deprecated_test.go @@ -283,52 +283,6 @@ func fmtKeepproxyConfig(param string, debugLog bool) string { `, debugLog, param) } -func (s *LoadSuite) TestLegacyArvGitHttpdConfig(c *check.C) { - content := []byte(` -{ - "Client": { - "Scheme": "", - "APIHost": "example.com", - "AuthToken": "abcdefg", - }, - "Listen": ":9000", - "GitCommand": "/test/git", - "GitoliteHome": "/test/gitolite", - "RepoRoot": "/test/reporoot", - "ManagementToken": "xyzzy" -} -`) - f := "-legacy-git-httpd-config" - cluster, err := testLoadLegacyConfig(content, f, c) - - c.Assert(err, check.IsNil) - c.Assert(cluster, check.NotNil) - c.Check(cluster.Services.Controller.ExternalURL, check.Equals, arvados.URL{Scheme: "https", Host: "example.com", Path: "/"}) - c.Check(cluster.SystemRootToken, check.Equals, "abcdefg") - c.Check(cluster.ManagementToken, check.Equals, "xyzzy") - c.Check(cluster.Git.GitCommand, check.Equals, "/test/git") - c.Check(cluster.Git.GitoliteHome, check.Equals, "/test/gitolite") - c.Check(cluster.Git.Repositories, check.Equals, "/test/reporoot") - c.Check(cluster.Services.Keepproxy.InternalURLs[arvados.URL{Host: ":9000"}], check.Equals, arvados.ServiceInstance{}) -} - -// Tests fix for https://dev.arvados.org/issues/15642 -func (s *LoadSuite) TestLegacyArvGitHttpdConfigDoesntDisableMissingItems(c *check.C) { - content := []byte(` -{ - "Client": { - "Scheme": "", - "APIHost": "example.com", - "AuthToken": "abcdefg", - } -} -`) - cluster, err := testLoadLegacyConfig(content, "-legacy-git-httpd-config", c) - c.Assert(err, check.IsNil) - // The resulting ManagementToken should be the one set up on the test server. - c.Check(cluster.ManagementToken, check.Equals, TestServerManagementToken) -} - func (s *LoadSuite) TestLegacyKeepBalanceConfig(c *check.C) { f := "-legacy-keepbalance-config" content := []byte(fmtKeepBalanceConfig("")) diff --git a/lib/config/export.go b/lib/config/export.go index f511ebbcb1..3c1e6bc008 100644 --- a/lib/config/export.go +++ b/lib/config/export.go @@ -59,108 +59,106 @@ func ExportJSON(w io.Writer, cluster *arvados.Cluster) error { // exists. var whitelist = map[string]bool{ // | sort -t'"' -k2,2 - "API": true, - "API.AsyncPermissionsUpdateInterval": false, - "API.DisabledAPIs": false, - "API.FreezeProjectRequiresDescription": true, - "API.FreezeProjectRequiresProperties": true, - "API.FreezeProjectRequiresProperties.*": true, - "API.KeepServiceRequestTimeout": false, - "API.LockBeforeUpdate": false, - "API.LogCreateRequestFraction": false, - "API.MaxConcurrentRailsRequests": false, - "API.MaxConcurrentRequests": false, - "API.MaxGatewayTunnels": false, - "API.MaxIndexDatabaseRead": false, - "API.MaxItemsPerResponse": true, - "API.MaxKeepBlobBuffers": false, - "API.MaxQueuedRequests": false, - "API.MaxQueueTimeForLockRequests": false, - "API.MaxRequestAmplification": false, - "API.MaxRequestSize": true, - "API.MaxTokenLifetime": false, - "API.RequestTimeout": true, - "API.SendTimeout": true, - "API.UnfreezeProjectRequiresAdmin": true, - "API.VocabularyPath": false, - "API.WebsocketClientEventQueue": false, - "API.WebsocketServerEventQueue": false, - "AuditLogs": false, - "AuditLogs.MaxAge": false, - "AuditLogs.MaxDeleteBatch": false, - "AuditLogs.UnloggedAttributes": false, - "ClusterID": true, - "Collections": true, - "Collections.BalanceCollectionBatch": false, - "Collections.BalanceCollectionBuffers": false, - "Collections.BalancePeriod": false, - "Collections.BalancePullLimit": false, - "Collections.BalanceTimeout": false, - "Collections.BalanceTrashLimit": false, - "Collections.BalanceUpdateLimit": false, - "Collections.BlobDeleteConcurrency": false, - "Collections.BlobMissingReport": false, - "Collections.BlobReplicateConcurrency": false, - "Collections.BlobSigning": true, - "Collections.BlobSigningKey": false, - "Collections.BlobSigningTTL": true, - "Collections.BlobTrash": false, - "Collections.BlobTrashCheckInterval": false, - "Collections.BlobTrashConcurrency": false, - "Collections.BlobTrashLifetime": false, - "Collections.CollectionVersioning": true, - "Collections.DefaultReplication": true, - "Collections.DefaultTrashLifetime": true, - "Collections.ForwardSlashNameSubstitution": true, - "Collections.KeepproxyPermission": false, - "Collections.ManagedProperties": true, - "Collections.ManagedProperties.*": true, - "Collections.ManagedProperties.*.*": true, - "Collections.PreserveVersionIfIdle": true, - "Collections.S3FolderObjects": true, - "Collections.TrashSweepInterval": false, - "Collections.TrustAllContent": true, - "Collections.WebDAVCache": false, - "Collections.WebDAVLogEvents": false, - "Collections.WebDAVOutputBuffer": false, - "Collections.WebDAVPermission": false, - "Containers": true, - "Containers.AlwaysUsePreemptibleInstances": true, - "Containers.CloudVMs": false, - "Containers.CrunchRunArgumentsList": false, - "Containers.CrunchRunCommand": false, - "Containers.DefaultKeepCacheRAM": true, - "Containers.DispatchPrivateKey": false, - "Containers.JobsAPI": true, - "Containers.JobsAPI.Enable": true, - "Containers.JobsAPI.GitInternalDir": false, - "Containers.LocalKeepBlobBuffersPerVCPU": false, - "Containers.LocalKeepLogsToContainerLog": false, - "Containers.Logging": false, - "Containers.LogReuseDecisions": false, - "Containers.LSF": false, - "Containers.MaxDispatchAttempts": false, - "Containers.MaximumPriceFactor": true, - "Containers.MaxRetryAttempts": true, - "Containers.MinRetryPeriod": true, - "Containers.PreemptiblePriceFactor": false, - "Containers.ReserveExtraRAM": true, - "Containers.RuntimeEngine": true, - "Containers.ShellAccess": true, - "Containers.ShellAccess.Admin": true, - "Containers.ShellAccess.User": true, - "Containers.SLURM": false, - "Containers.StaleLockTimeout": false, - "Containers.SupportedDockerImageFormats": true, - "Containers.SupportedDockerImageFormats.*": true, - "Git": false, - "InstanceTypes": true, - "InstanceTypes.*": true, - "InstanceTypes.*.*": true, - "InstanceTypes.*.*.*": true, - "Login": true, - "Login.Google": true, - "Login.Google.AlternateEmailAddresses": false, + "API": true, + "API.AsyncPermissionsUpdateInterval": false, + "API.DisabledAPIs": false, + "API.FreezeProjectRequiresDescription": true, + "API.FreezeProjectRequiresProperties": true, + "API.FreezeProjectRequiresProperties.*": true, + "API.KeepServiceRequestTimeout": false, + "API.LockBeforeUpdate": false, + "API.LogCreateRequestFraction": false, + "API.MaxConcurrentRailsRequests": false, + "API.MaxConcurrentRequests": false, + "API.MaxGatewayTunnels": false, + "API.MaxIndexDatabaseRead": false, + "API.MaxItemsPerResponse": true, + "API.MaxKeepBlobBuffers": false, + "API.MaxQueuedRequests": false, + "API.MaxQueueTimeForLockRequests": false, + "API.MaxRequestAmplification": false, + "API.MaxRequestSize": true, + "API.MaxTokenLifetime": false, + "API.RequestTimeout": true, + "API.SendTimeout": true, + "API.UnfreezeProjectRequiresAdmin": true, + "API.VocabularyPath": false, + "API.WebsocketClientEventQueue": false, + "API.WebsocketServerEventQueue": false, + "AuditLogs": false, + "AuditLogs.MaxAge": false, + "AuditLogs.MaxDeleteBatch": false, + "AuditLogs.UnloggedAttributes": false, + "ClusterID": true, + "Collections": true, + "Collections.BalanceCollectionBatch": false, + "Collections.BalanceCollectionBuffers": false, + "Collections.BalancePeriod": false, + "Collections.BalancePullLimit": false, + "Collections.BalanceTimeout": false, + "Collections.BalanceTrashLimit": false, + "Collections.BalanceUpdateLimit": false, + "Collections.BlobDeleteConcurrency": false, + "Collections.BlobMissingReport": false, + "Collections.BlobReplicateConcurrency": false, + "Collections.BlobSigning": true, + "Collections.BlobSigningKey": false, + "Collections.BlobSigningTTL": true, + "Collections.BlobTrash": false, + "Collections.BlobTrashCheckInterval": false, + "Collections.BlobTrashConcurrency": false, + "Collections.BlobTrashLifetime": false, + "Collections.CollectionVersioning": true, + "Collections.DefaultReplication": true, + "Collections.DefaultTrashLifetime": true, + "Collections.ForwardSlashNameSubstitution": true, + "Collections.KeepproxyPermission": false, + "Collections.ManagedProperties": true, + "Collections.ManagedProperties.*": true, + "Collections.ManagedProperties.*.*": true, + "Collections.PreserveVersionIfIdle": true, + "Collections.S3FolderObjects": true, + "Collections.TrashSweepInterval": false, + "Collections.TrustAllContent": true, + "Collections.WebDAVCache": false, + "Collections.WebDAVLogEvents": false, + "Collections.WebDAVOutputBuffer": false, + "Collections.WebDAVPermission": false, + "Containers": true, + "Containers.AlwaysUsePreemptibleInstances": true, + "Containers.CloudVMs": false, + "Containers.CrunchRunArgumentsList": false, + "Containers.CrunchRunCommand": false, + "Containers.DefaultKeepCacheRAM": true, + "Containers.DispatchPrivateKey": false, + "Containers.JobsAPI": true, + "Containers.JobsAPI.Enable": true, + "Containers.LocalKeepBlobBuffersPerVCPU": false, + "Containers.LocalKeepLogsToContainerLog": false, + "Containers.Logging": false, + "Containers.LogReuseDecisions": false, + "Containers.LSF": false, + "Containers.MaxDispatchAttempts": false, + "Containers.MaximumPriceFactor": true, + "Containers.MaxRetryAttempts": true, + "Containers.MinRetryPeriod": true, + "Containers.PreemptiblePriceFactor": false, + "Containers.ReserveExtraRAM": true, + "Containers.RuntimeEngine": true, + "Containers.ShellAccess": true, + "Containers.ShellAccess.Admin": true, + "Containers.ShellAccess.User": true, + "Containers.SLURM": false, + "Containers.StaleLockTimeout": false, + "Containers.SupportedDockerImageFormats": true, + "Containers.SupportedDockerImageFormats.*": true, + "InstanceTypes": true, + "InstanceTypes.*": true, + "InstanceTypes.*.*": true, + "InstanceTypes.*.*.*": true, + "Login": true, + "Login.Google": true, + "Login.Google.AlternateEmailAddresses": false, "Login.Google.AuthenticationRequestParameters": false, "Login.Google.ClientID": false, "Login.Google.ClientSecret": false, @@ -243,7 +241,6 @@ var whitelist = map[string]bool{ "Users.AutoAdminFirstUser": false, "Users.AutoAdminUserWithEmail": false, "Users.AutoSetupNewUsers": false, - "Users.AutoSetupNewUsersWithRepository": false, "Users.AutoSetupNewUsersWithVmUUID": false, "Users.AutoSetupUsernameBlacklist": false, "Users.CanCreateRoleGroups": true, diff --git a/lib/config/load.go b/lib/config/load.go index d504f7796c..00c8e28683 100644 --- a/lib/config/load.go +++ b/lib/config/load.go @@ -48,7 +48,6 @@ type Loader struct { CrunchDispatchSlurmPath string WebsocketPath string KeepproxyPath string - GitHttpdPath string KeepBalancePath string configdata []byte @@ -88,7 +87,6 @@ func (ldr *Loader) SetupFlags(flagset *flag.FlagSet) { flagset.StringVar(&ldr.CrunchDispatchSlurmPath, "legacy-crunch-dispatch-slurm-config", defaultCrunchDispatchSlurmConfigPath, "Legacy crunch-dispatch-slurm configuration `file`") flagset.StringVar(&ldr.WebsocketPath, "legacy-ws-config", defaultWebsocketConfigPath, "Legacy arvados-ws configuration `file`") flagset.StringVar(&ldr.KeepproxyPath, "legacy-keepproxy-config", defaultKeepproxyConfigPath, "Legacy keepproxy configuration `file`") - flagset.StringVar(&ldr.GitHttpdPath, "legacy-git-httpd-config", defaultGitHttpdConfigPath, "Legacy arvados-git-httpd configuration `file`") flagset.StringVar(&ldr.KeepBalancePath, "legacy-keepbalance-config", defaultKeepBalanceConfigPath, "Legacy keep-balance configuration `file`") flagset.BoolVar(&ldr.SkipLegacy, "skip-legacy", false, "Don't load legacy config files") } @@ -168,9 +166,6 @@ func (ldr *Loader) MungeLegacyConfigArgs(lgr logrus.FieldLogger, args []string, if legacyConfigArg != "-legacy-keepproxy-config" { ldr.KeepproxyPath = "" } - if legacyConfigArg != "-legacy-git-httpd-config" { - ldr.GitHttpdPath = "" - } if legacyConfigArg != "-legacy-keepbalance-config" { ldr.KeepBalancePath = "" } @@ -296,7 +291,6 @@ func (ldr *Loader) Load() (*arvados.Config, error) { ldr.loadOldCrunchDispatchSlurmConfig, ldr.loadOldWebsocketConfig, ldr.loadOldKeepproxyConfig, - ldr.loadOldGitHttpdConfig, ldr.loadOldKeepBalanceConfig, ) } diff --git a/lib/controller/federation/conn.go b/lib/controller/federation/conn.go index 949cc56dd2..c2cbfec008 100644 --- a/lib/controller/federation/conn.go +++ b/lib/controller/federation/conn.go @@ -605,26 +605,6 @@ func (conn *Conn) LogDelete(ctx context.Context, options arvados.DeleteOptions) return conn.chooseBackend(options.UUID).LogDelete(ctx, options) } -func (conn *Conn) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) { - return conn.generated_SpecimenList(ctx, options) -} - -func (conn *Conn) SpecimenCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Specimen, error) { - return conn.chooseBackend(options.ClusterID).SpecimenCreate(ctx, options) -} - -func (conn *Conn) SpecimenUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Specimen, error) { - return conn.chooseBackend(options.UUID).SpecimenUpdate(ctx, options) -} - -func (conn *Conn) SpecimenGet(ctx context.Context, options arvados.GetOptions) (arvados.Specimen, error) { - return conn.chooseBackend(options.UUID).SpecimenGet(ctx, options) -} - -func (conn *Conn) SpecimenDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Specimen, error) { - return conn.chooseBackend(options.UUID).SpecimenDelete(ctx, options) -} - func (conn *Conn) SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error) { return conn.local.SysTrashSweep(ctx, options) } diff --git a/lib/controller/federation/generate.go b/lib/controller/federation/generate.go index 2dc2918f79..079d908f0d 100644 --- a/lib/controller/federation/generate.go +++ b/lib/controller/federation/generate.go @@ -53,7 +53,7 @@ func main() { defer out.Close() out.Write(regexp.MustCompile(`(?ms)^.*package .*?import.*?\n\)\n`).Find(buf)) io.WriteString(out, "//\n// -- this file is auto-generated -- do not edit -- edit list.go and run \"go generate\" instead --\n//\n\n") - for _, t := range []string{"AuthorizedKey", "Container", "ContainerRequest", "Group", "Specimen", "User", "Link", "Log", "APIClientAuthorization"} { + for _, t := range []string{"AuthorizedKey", "Container", "ContainerRequest", "Group", "User", "Link", "Log", "APIClientAuthorization"} { _, err := out.Write(bytes.ReplaceAll(orig, []byte("Collection"), []byte(t))) if err != nil { panic(err) diff --git a/lib/controller/federation/generated.go b/lib/controller/federation/generated.go index 8c8666fea1..95f2f650fc 100755 --- a/lib/controller/federation/generated.go +++ b/lib/controller/federation/generated.go @@ -181,47 +181,6 @@ func (conn *Conn) generated_GroupList(ctx context.Context, options arvados.ListO return merged, err } -func (conn *Conn) generated_SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) { - var mtx sync.Mutex - var merged arvados.SpecimenList - var needSort atomic.Value - needSort.Store(false) - err := conn.splitListRequest(ctx, options, func(ctx context.Context, _ string, backend arvados.API, options arvados.ListOptions) ([]string, error) { - options.ForwardedFor = conn.cluster.ClusterID + "-" + options.ForwardedFor - cl, err := backend.SpecimenList(ctx, options) - if err != nil { - return nil, err - } - mtx.Lock() - defer mtx.Unlock() - if len(merged.Items) == 0 { - merged = cl - } else if len(cl.Items) > 0 { - merged.Items = append(merged.Items, cl.Items...) - needSort.Store(true) - } - uuids := make([]string, 0, len(cl.Items)) - for _, item := range cl.Items { - uuids = append(uuids, item.UUID) - } - return uuids, nil - }) - if needSort.Load().(bool) { - // Apply the default/implied order, "modified_at desc" - sort.Slice(merged.Items, func(i, j int) bool { - mi, mj := merged.Items[i].ModifiedAt, merged.Items[j].ModifiedAt - return mj.Before(mi) - }) - } - if merged.Items == nil { - // Return empty results as [], not null - // (https://github.com/golang/go/issues/27589 might be - // a better solution in the future) - merged.Items = []arvados.Specimen{} - } - return merged, err -} - func (conn *Conn) generated_UserList(ctx context.Context, options arvados.ListOptions) (arvados.UserList, error) { var mtx sync.Mutex var merged arvados.UserList diff --git a/lib/controller/handler_test.go b/lib/controller/handler_test.go index eef0443b9a..ff1d43da41 100644 --- a/lib/controller/handler_test.go +++ b/lib/controller/handler_test.go @@ -20,6 +20,7 @@ import ( "testing" "time" + "git.arvados.org/arvados.git/lib/controller/dblock" "git.arvados.org/arvados.git/lib/controller/rpc" "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/arvadostest" @@ -65,6 +66,25 @@ func (s *HandlerSuite) SetUpTest(c *check.C) { func (s *HandlerSuite) TearDownTest(c *check.C) { s.cancel() + + // Wait for dblocks to be released. Otherwise, a subsequent + // test might time out waiting to acquire them. + timeout := time.After(10 * time.Second) + for _, locker := range []*dblock.DBLocker{dblock.TrashSweep, dblock.ContainerLogSweep} { + ok := make(chan struct{}) + go func() { + if locker.Lock(context.Background(), s.handler.dbConnector.GetDB) { + locker.Unlock() + } + close(ok) + }() + select { + case <-timeout: + c.Log("timed out waiting for dblocks") + c.Fail() + case <-ok: + } + } } func (s *HandlerSuite) TestConfigExport(c *check.C) { @@ -568,8 +588,10 @@ func (s *HandlerSuite) CheckObjectType(c *check.C, url string, token string, ski req.Header.Set("Authorization", "Bearer "+token) resp := httptest.NewRecorder() s.handler.ServeHTTP(resp, req) - c.Assert(resp.Code, check.Equals, http.StatusOK, - check.Commentf("Wasn't able to get data from the controller at %q: %q", url, resp.Body.String())) + if !c.Check(resp.Code, check.Equals, http.StatusOK, + check.Commentf("Wasn't able to get data from the controller at %q: %q", url, resp.Body.String())) { + return + } err = json.Unmarshal(resp.Body.Bytes(), &proxied) c.Check(err, check.Equals, nil) @@ -581,9 +603,11 @@ func (s *HandlerSuite) CheckObjectType(c *check.C, url string, token string, ski } resp2, err := client.Get(s.cluster.Services.RailsAPI.ExternalURL.String() + url + "/?api_token=" + token) c.Check(err, check.Equals, nil) - c.Assert(resp2.StatusCode, check.Equals, http.StatusOK, - check.Commentf("Wasn't able to get data from the RailsAPI at %q", url)) defer resp2.Body.Close() + if !c.Check(resp2.StatusCode, check.Equals, http.StatusOK, + check.Commentf("Wasn't able to get data from the RailsAPI at %q", url)) { + return + } db, err := ioutil.ReadAll(resp2.Body) c.Check(err, check.Equals, nil) err = json.Unmarshal(db, &direct) @@ -647,9 +671,7 @@ func (s *HandlerSuite) TestGetObjects(c *check.C) { "groups/" + arvadostest.AProjectUUID: nil, "keep_services/" + ksUUID: nil, "links/" + arvadostest.ActiveUserCanReadAllUsersLinkUUID: nil, - "logs/" + arvadostest.CrunchstatForRunningJobLogUUID: nil, - "nodes/" + arvadostest.IdleNodeUUID: nil, - "repositories/" + arvadostest.ArvadosRepoUUID: nil, + "logs/" + arvadostest.CrunchstatForRunningContainerLogUUID: nil, "users/" + arvadostest.ActiveUserUUID: {"href": true}, "virtual_machines/" + arvadostest.TestVMUUID: nil, "workflows/" + arvadostest.WorkflowWithDefinitionYAMLUUID: nil, @@ -705,14 +727,14 @@ func (s *HandlerSuite) TestTrashSweep(c *check.C) { func (s *HandlerSuite) TestContainerLogSweep(c *check.C) { s.cluster.SystemRootToken = arvadostest.SystemRootToken - s.cluster.Containers.Logging.SweepInterval = arvados.Duration(time.Second / 10) + s.cluster.Collections.TrashSweepInterval = arvados.Duration(2 * time.Second) s.handler.CheckHealth() ctx := auth.NewContext(s.ctx, &auth.Credentials{Tokens: []string{arvadostest.ActiveTokenV2}}) logentry, err := s.handler.federation.LogCreate(ctx, arvados.CreateOptions{Attrs: map[string]interface{}{ "object_uuid": arvadostest.CompletedContainerUUID, "event_type": "stderr", "properties": map[string]interface{}{ - "text": "test trash sweep\n", + "text": "test container log sweep\n", }, }}) c.Assert(err, check.IsNil) diff --git a/lib/controller/integration_test.go b/lib/controller/integration_test.go index 45f35a6d2e..18a0c1992b 100644 --- a/lib/controller/integration_test.go +++ b/lib/controller/integration_test.go @@ -604,8 +604,6 @@ func (s *IntegrationSuite) TestRequestIDHeader(c *check.C) { coll, err := conn1.CollectionCreate(userctx1, arvados.CreateOptions{}) c.Check(err, check.IsNil) - specimen, err := conn1.SpecimenCreate(userctx1, arvados.CreateOptions{}) - c.Check(err, check.IsNil) tests := []struct { path string @@ -618,8 +616,6 @@ func (s *IntegrationSuite) TestRequestIDHeader(c *check.C) { {"/arvados/v1/nonexistant", true, true}, {"/arvados/v1/collections/" + coll.UUID, false, false}, {"/arvados/v1/collections/" + coll.UUID, true, false}, - {"/arvados/v1/specimens/" + specimen.UUID, false, false}, - {"/arvados/v1/specimens/" + specimen.UUID, true, false}, // new code path (lib/controller/router etc) - single-cluster request {"/arvados/v1/collections/z1111-4zz18-0123456789abcde", false, true}, {"/arvados/v1/collections/z1111-4zz18-0123456789abcde", true, true}, @@ -627,8 +623,8 @@ func (s *IntegrationSuite) TestRequestIDHeader(c *check.C) { {"/arvados/v1/collections/z2222-4zz18-0123456789abcde", false, true}, {"/arvados/v1/collections/z2222-4zz18-0123456789abcde", true, true}, // old code path (proxyRailsAPI) - single-cluster request - {"/arvados/v1/specimens/z1111-j58dm-0123456789abcde", false, true}, - {"/arvados/v1/specimens/z1111-j58dm-0123456789abcde", true, true}, + {"/arvados/v1/containers/z1111-dz642-0123456789abcde", false, true}, + {"/arvados/v1/containers/z1111-dz642-0123456789abcde", true, true}, // old code path (setupProxyRemoteCluster) - federated request {"/arvados/v1/workflows/z2222-7fd4e-0123456789abcde", false, true}, {"/arvados/v1/workflows/z2222-7fd4e-0123456789abcde", true, true}, @@ -830,7 +826,6 @@ func (s *IntegrationSuite) TestFederatedApiClientAuthHandling(c *check.C) { // Test for bug #18076 func (s *IntegrationSuite) TestStaleCachedUserRecord(c *check.C) { rootctx1, _, _ := s.super.RootClients("z1111") - _, rootclnt3, _ := s.super.RootClients("z3333") conn1 := s.super.Conn("z1111") conn3 := s.super.Conn("z3333") @@ -842,92 +837,69 @@ func (s *IntegrationSuite) TestStaleCachedUserRecord(c *check.C) { check.Commentf("incorrect LoginCluster config on cluster %q", cls)) } - for testCaseNr, testCase := range []struct { - name string - withRepository bool - }{ - {"User without local repository", false}, - {"User with local repository", true}, - } { - c.Log(c.TestName() + " " + testCase.name) - // Create some users, request them on the federated cluster so they're cached. - var users []arvados.User - for userNr := 0; userNr < 2; userNr++ { - _, _, _, user := s.super.UserClients("z1111", - rootctx1, - c, - conn1, - fmt.Sprintf("user%d%d@example.com", testCaseNr, userNr), - true) - c.Assert(user.Username, check.Not(check.Equals), "") - users = append(users, user) - - lst, err := conn3.UserList(rootctx1, arvados.ListOptions{Limit: -1}) - c.Assert(err, check.Equals, nil) - userFound := false - for _, fedUser := range lst.Items { - if fedUser.UUID == user.UUID { - c.Assert(fedUser.Username, check.Equals, user.Username) - userFound = true - break - } - } - c.Assert(userFound, check.Equals, true) - - if testCase.withRepository { - var repo interface{} - err = rootclnt3.RequestAndDecode( - &repo, "POST", "arvados/v1/repositories", nil, - map[string]interface{}{ - "repository": map[string]string{ - "name": fmt.Sprintf("%s/test", user.Username), - "owner_uuid": user.UUID, - }, - }, - ) - c.Assert(err, check.IsNil) - } - } - - // Swap the usernames - _, err := conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ - UUID: users[0].UUID, - Attrs: map[string]interface{}{ - "username": "", - }, - }) - c.Assert(err, check.Equals, nil) - _, err = conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ - UUID: users[1].UUID, - Attrs: map[string]interface{}{ - "username": users[0].Username, - }, - }) - c.Assert(err, check.Equals, nil) - _, err = conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ - UUID: users[0].UUID, - Attrs: map[string]interface{}{ - "username": users[1].Username, - }, - }) - c.Assert(err, check.Equals, nil) + // Create some users, request them on the federated cluster so they're cached. + var users []arvados.User + for userNr := 0; userNr < 2; userNr++ { + _, _, _, user := s.super.UserClients("z1111", + rootctx1, + c, + conn1, + fmt.Sprintf("user0%d@example.com", userNr), + true) + c.Assert(user.Username, check.Not(check.Equals), "") + users = append(users, user) - // Re-request the list on the federated cluster & check for updates lst, err := conn3.UserList(rootctx1, arvados.ListOptions{Limit: -1}) c.Assert(err, check.Equals, nil) - var user0Found, user1Found bool - for _, user := range lst.Items { - if user.UUID == users[0].UUID { - user0Found = true - c.Assert(user.Username, check.Equals, users[1].Username) - } else if user.UUID == users[1].UUID { - user1Found = true - c.Assert(user.Username, check.Equals, users[0].Username) + userFound := false + for _, fedUser := range lst.Items { + if fedUser.UUID == user.UUID { + c.Assert(fedUser.Username, check.Equals, user.Username) + userFound = true + break } } - c.Assert(user0Found, check.Equals, true) - c.Assert(user1Found, check.Equals, true) + c.Assert(userFound, check.Equals, true) + } + + // Swap the usernames + _, err := conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ + UUID: users[0].UUID, + Attrs: map[string]interface{}{ + "username": "", + }, + }) + c.Assert(err, check.Equals, nil) + _, err = conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ + UUID: users[1].UUID, + Attrs: map[string]interface{}{ + "username": users[0].Username, + }, + }) + c.Assert(err, check.Equals, nil) + _, err = conn1.UserUpdate(rootctx1, arvados.UpdateOptions{ + UUID: users[0].UUID, + Attrs: map[string]interface{}{ + "username": users[1].Username, + }, + }) + c.Assert(err, check.Equals, nil) + + // Re-request the list on the federated cluster & check for updates + lst, err := conn3.UserList(rootctx1, arvados.ListOptions{Limit: -1}) + c.Assert(err, check.Equals, nil) + var user0Found, user1Found bool + for _, user := range lst.Items { + if user.UUID == users[0].UUID { + user0Found = true + c.Assert(user.Username, check.Equals, users[1].Username) + } else if user.UUID == users[1].UUID { + user1Found = true + c.Assert(user.Username, check.Equals, users[0].Username) + } } + c.Assert(user0Found, check.Equals, true) + c.Assert(user1Found, check.Equals, true) } // Test for bug #16263 @@ -1339,10 +1311,12 @@ func (s *IntegrationSuite) runContainer(c *check.C, clusterID string, token stri err = ac.RequestAndDecode(&outcoll, "GET", "/arvados/v1/collections/"+cr.OutputUUID, nil, nil) c.Assert(err, check.IsNil) c.Check(allStatus, check.Matches, `Queued, waiting for dispatch\n`+ - `(Queued, waiting.*\n)*`+ - `(Locked, waiting for dispatch\n)?`+ - `(Locked, waiting for new instance to be ready\n)?`+ - `(Locked, preparing runtime environment\n)?`+ + // Occasionally the dispatcher will + // unlock/retry, and we get state/status from + // database/dispatcher via separate API calls, + // so we can also see "Queued, preparing + // runtime environment". + `((Queued|Locked), (waiting .*|preparing runtime environment)\n)*`+ `(Running, \n)?`+ `Complete, \n`) } diff --git a/lib/controller/localdb/log_activity.go b/lib/controller/localdb/log_activity.go index 9c9660aec4..9f9674e08b 100644 --- a/lib/controller/localdb/log_activity.go +++ b/lib/controller/localdb/log_activity.go @@ -13,10 +13,15 @@ import ( "git.arvados.org/arvados.git/sdk/go/ctxlog" ) +var loggedLogActivityDisabled = false + func (conn *Conn) logActivity(ctx context.Context) { p := conn.cluster.Users.ActivityLoggingPeriod.Duration() if p < 1 { - ctxlog.FromContext(ctx).Debug("logActivity disabled by config") + if !loggedLogActivityDisabled { + ctxlog.FromContext(ctx).Debug("logActivity disabled by config") + loggedLogActivityDisabled = true + } return } user, _, err := ctrlctx.CurrentAuth(ctx) diff --git a/lib/controller/router/response.go b/lib/controller/router/response.go index 42b3435593..97b84df735 100644 --- a/lib/controller/router/response.go +++ b/lib/controller/router/response.go @@ -143,11 +143,6 @@ var infixMap = map[string]interface{}{ "xvhdp": arvados.ContainerRequest{}, "dz642": arvados.Container{}, "j7d0g": arvados.Group{}, - "8i9sb": arvados.Job{}, - "d1hrv": arvados.PipelineInstance{}, - "p5p6p": arvados.PipelineTemplate{}, - "j58dm": arvados.Specimen{}, - "q1cn2": arvados.Trait{}, "7fd4e": arvados.Workflow{}, } diff --git a/lib/controller/router/router.go b/lib/controller/router/router.go index 054bcffaf7..39c7d871d8 100644 --- a/lib/controller/router/router.go +++ b/lib/controller/router/router.go @@ -472,41 +472,6 @@ func (rtr *router) addRoutes() { return rtr.backend.LogDelete(ctx, *opts.(*arvados.DeleteOptions)) }, }, - { - arvados.EndpointSpecimenCreate, - func() interface{} { return &arvados.CreateOptions{} }, - func(ctx context.Context, opts interface{}) (interface{}, error) { - return rtr.backend.SpecimenCreate(ctx, *opts.(*arvados.CreateOptions)) - }, - }, - { - arvados.EndpointSpecimenUpdate, - func() interface{} { return &arvados.UpdateOptions{} }, - func(ctx context.Context, opts interface{}) (interface{}, error) { - return rtr.backend.SpecimenUpdate(ctx, *opts.(*arvados.UpdateOptions)) - }, - }, - { - arvados.EndpointSpecimenGet, - func() interface{} { return &arvados.GetOptions{} }, - func(ctx context.Context, opts interface{}) (interface{}, error) { - return rtr.backend.SpecimenGet(ctx, *opts.(*arvados.GetOptions)) - }, - }, - { - arvados.EndpointSpecimenList, - func() interface{} { return &arvados.ListOptions{Limit: -1} }, - func(ctx context.Context, opts interface{}) (interface{}, error) { - return rtr.backend.SpecimenList(ctx, *opts.(*arvados.ListOptions)) - }, - }, - { - arvados.EndpointSpecimenDelete, - func() interface{} { return &arvados.DeleteOptions{} }, - func(ctx context.Context, opts interface{}) (interface{}, error) { - return rtr.backend.SpecimenDelete(ctx, *opts.(*arvados.DeleteOptions)) - }, - }, { arvados.EndpointAPIClientAuthorizationCreate, func() interface{} { return &arvados.CreateOptions{} }, diff --git a/lib/controller/rpc/conn.go b/lib/controller/rpc/conn.go index c6be679a25..3125ae29be 100644 --- a/lib/controller/rpc/conn.go +++ b/lib/controller/rpc/conn.go @@ -682,41 +682,6 @@ func (conn *Conn) LogDelete(ctx context.Context, options arvados.DeleteOptions) return resp, err } -func (conn *Conn) SpecimenCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Specimen, error) { - ep := arvados.EndpointSpecimenCreate - var resp arvados.Specimen - err := conn.requestAndDecode(ctx, &resp, ep, nil, options) - return resp, err -} - -func (conn *Conn) SpecimenUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Specimen, error) { - ep := arvados.EndpointSpecimenUpdate - var resp arvados.Specimen - err := conn.requestAndDecode(ctx, &resp, ep, nil, options) - return resp, err -} - -func (conn *Conn) SpecimenGet(ctx context.Context, options arvados.GetOptions) (arvados.Specimen, error) { - ep := arvados.EndpointSpecimenGet - var resp arvados.Specimen - err := conn.requestAndDecode(ctx, &resp, ep, nil, options) - return resp, err -} - -func (conn *Conn) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) { - ep := arvados.EndpointSpecimenList - var resp arvados.SpecimenList - err := conn.requestAndDecode(ctx, &resp, ep, nil, options) - return resp, err -} - -func (conn *Conn) SpecimenDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Specimen, error) { - ep := arvados.EndpointSpecimenDelete - var resp arvados.Specimen - err := conn.requestAndDecode(ctx, &resp, ep, nil, options) - return resp, err -} - func (conn *Conn) SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error) { ep := arvados.EndpointSysTrashSweep var resp struct{} diff --git a/lib/controller/rpc/conn_test.go b/lib/controller/rpc/conn_test.go index 0d1200fe12..ed26e04117 100644 --- a/lib/controller/rpc/conn_test.go +++ b/lib/controller/rpc/conn_test.go @@ -100,23 +100,24 @@ func (s *RPCSuite) TestCollectionCreate(c *check.C) { c.Check(coll.UUID, check.HasLen, 27) } -func (s *RPCSuite) TestSpecimenCRUD(c *check.C) { +func (s *RPCSuite) TestGroupCRUD(c *check.C) { s.setupConn(c, os.Getenv("ARVADOS_TEST_API_HOST")) - sp, err := s.conn.SpecimenCreate(s.ctx, arvados.CreateOptions{Attrs: map[string]interface{}{ - "owner_uuid": arvadostest.ActiveUserUUID, - "properties": map[string]string{"foo": "bar"}, + sp, err := s.conn.GroupCreate(s.ctx, arvados.CreateOptions{Attrs: map[string]interface{}{ + "group_class": "project", + "owner_uuid": arvadostest.ActiveUserUUID, + "properties": map[string]string{"foo": "bar"}, }}) c.Check(err, check.IsNil) c.Check(sp.UUID, check.HasLen, 27) c.Check(sp.Properties, check.HasLen, 1) c.Check(sp.Properties["foo"], check.Equals, "bar") - spGet, err := s.conn.SpecimenGet(s.ctx, arvados.GetOptions{UUID: sp.UUID}) + spGet, err := s.conn.GroupGet(s.ctx, arvados.GetOptions{UUID: sp.UUID}) c.Check(err, check.IsNil) c.Check(spGet.UUID, check.Equals, sp.UUID) c.Check(spGet.Properties["foo"], check.Equals, "bar") - spList, err := s.conn.SpecimenList(s.ctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", sp.UUID}}}) + spList, err := s.conn.GroupList(s.ctx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", sp.UUID}}}) c.Check(err, check.IsNil) c.Check(spList.ItemsAvailable, check.Equals, 1) c.Assert(spList.Items, check.HasLen, 1) @@ -124,12 +125,12 @@ func (s *RPCSuite) TestSpecimenCRUD(c *check.C) { c.Check(spList.Items[0].Properties["foo"], check.Equals, "bar") anonCtx := context.WithValue(context.Background(), contextKeyTestTokens, []string{arvadostest.AnonymousToken}) - spList, err = s.conn.SpecimenList(anonCtx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", sp.UUID}}}) + spList, err = s.conn.GroupList(anonCtx, arvados.ListOptions{Limit: -1, Filters: []arvados.Filter{{"uuid", "=", sp.UUID}}}) c.Check(err, check.IsNil) c.Check(spList.ItemsAvailable, check.Equals, 0) c.Check(spList.Items, check.HasLen, 0) - spDel, err := s.conn.SpecimenDelete(s.ctx, arvados.DeleteOptions{UUID: sp.UUID}) + spDel, err := s.conn.GroupDelete(s.ctx, arvados.DeleteOptions{UUID: sp.UUID}) c.Check(err, check.IsNil) c.Check(spDel.UUID, check.Equals, sp.UUID) } diff --git a/lib/controller/trash.go b/lib/controller/trash.go index 99e7aec0b6..662ea26751 100644 --- a/lib/controller/trash.go +++ b/lib/controller/trash.go @@ -25,7 +25,7 @@ func (h *Handler) periodicWorker(workerName string, interval time.Duration, lock return } defer locker.Unlock() - for time.Sleep(interval); ctx.Err() == nil; time.Sleep(interval) { + for ctxSleep(ctx, interval); ctx.Err() == nil; ctxSleep(ctx, interval) { if !locker.Check() { // context canceled return @@ -46,7 +46,19 @@ func (h *Handler) trashSweepWorker() { } func (h *Handler) containerLogSweepWorker() { - h.periodicWorker("container log sweep", h.Cluster.Containers.Logging.SweepInterval.Duration(), dblock.ContainerLogSweep, func(ctx context.Context) error { + // Since #21611 we don't expect any new log entries, so the + // periodic worker only runs once, then becomes a no-op. + // + // The old Containers.Logging.SweepInterval config is removed. + // We use TrashSweepInterval here instead, for testing + // reasons: it prevents the default integration-testing + // controller service (whose TrashSweepInterval is 0) from + // acquiring the dblock. + done := false + h.periodicWorker("container log sweep", h.Cluster.Collections.TrashSweepInterval.Duration(), dblock.ContainerLogSweep, func(ctx context.Context) error { + if done { + return nil + } db, err := h.dbConnector.GetDB(ctx) if err != nil { return err @@ -56,9 +68,7 @@ DELETE FROM logs USING containers WHERE logs.object_uuid=containers.uuid AND logs.event_type in ('stdout', 'stderr', 'arv-mount', 'crunch-run', 'crunchstat', 'hoststat', 'node', 'container', 'keepstore') - AND containers.log IS NOT NULL - AND now() - containers.finished_at > $1::interval`, - h.Cluster.Containers.Logging.MaxAge.String()) + AND containers.log IS NOT NULL`) if err != nil { return err } @@ -68,7 +78,19 @@ DELETE FROM logs logger.WithError(err).Warn("unexpected error from RowsAffected()") } else { logger.WithField("rows", rows).Info("deleted rows from logs table") + if rows == 0 { + done = true + } } return nil }) } + +// Sleep for the given duration, but return early if ctx cancels +// before that. +func ctxSleep(ctx context.Context, d time.Duration) { + select { + case <-ctx.Done(): + case <-time.After(d): + } +} diff --git a/lib/crunchrun/copier.go b/lib/crunchrun/copier.go index a081c5d325..b411948733 100644 --- a/lib/crunchrun/copier.go +++ b/lib/crunchrun/copier.go @@ -9,6 +9,7 @@ import ( "errors" "fmt" "io" + "io/fs" "os" "path/filepath" "sort" @@ -17,6 +18,7 @@ import ( "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/keepclient" "git.arvados.org/arvados.git/sdk/go/manifest" + "github.com/bmatcuk/doublestar/v4" ) type printfer interface { @@ -54,6 +56,7 @@ type copier struct { keepClient IKeepClient hostOutputDir string ctrOutputDir string + globs []string bindmounts map[string]bindmount mounts map[string]arvados.Mount secretMounts map[string]arvados.Mount @@ -72,16 +75,29 @@ func (cp *copier) Copy() (string, error) { if err != nil { return "", fmt.Errorf("error scanning files to copy to output: %v", err) } - fs, err := (&arvados.Collection{ManifestText: cp.manifest}).FileSystem(cp.client, cp.keepClient) + collfs, err := (&arvados.Collection{ManifestText: cp.manifest}).FileSystem(cp.client, cp.keepClient) if err != nil { return "", fmt.Errorf("error creating Collection.FileSystem: %v", err) } + + // Remove files/dirs that don't match globs (the ones that + // were added during cp.walkMount() by copying subtree + // manifests into cp.manifest). + err = cp.applyGlobsToCollectionFS(collfs) + if err != nil { + return "", fmt.Errorf("error while removing non-matching files from output collection: %w", err) + } + // Remove files/dirs that don't match globs (the ones that are + // stored on the local filesystem and would need to be copied + // in copyFile() below). + cp.applyGlobsToFilesAndDirs() for _, d := range cp.dirs { - err = fs.Mkdir(d, 0777) + err = collfs.Mkdir(d, 0777) if err != nil && err != os.ErrExist { return "", fmt.Errorf("error making directory %q in output collection: %v", d, err) } } + var unflushed int64 var lastparentdir string for _, f := range cp.files { @@ -91,20 +107,184 @@ func (cp *copier) Copy() (string, error) { // open so f's data can be packed with it). dir, _ := filepath.Split(f.dst) if dir != lastparentdir || unflushed > keepclient.BLOCKSIZE { - if err := fs.Flush("/"+lastparentdir, dir != lastparentdir); err != nil { + if err := collfs.Flush("/"+lastparentdir, dir != lastparentdir); err != nil { return "", fmt.Errorf("error flushing output collection file data: %v", err) } unflushed = 0 } lastparentdir = dir - n, err := cp.copyFile(fs, f) + n, err := cp.copyFile(collfs, f) if err != nil { return "", fmt.Errorf("error copying file %q into output collection: %v", f, err) } unflushed += n } - return fs.MarshalManifest(".") + return collfs.MarshalManifest(".") +} + +func (cp *copier) matchGlobs(path string, isDir bool) bool { + // An entry in the top level of the output directory looks + // like "/foo", but globs look like "foo", so we strip the + // leading "/" before matching. + path = strings.TrimLeft(path, "/") + for _, glob := range cp.globs { + if !isDir && strings.HasSuffix(glob, "/**") { + // doublestar.Match("f*/**", "ff") and + // doublestar.Match("f*/**", "ff/gg") both + // return true, but (to be compatible with + // bash shopt) "ff" should match only if it is + // a directory. + // + // To avoid errant matches, we add the file's + // basename to the end of the pattern: + // + // Match("f*/**/ff", "ff") => false + // Match("f*/**/gg", "ff/gg") => true + // + // Of course, we need to escape basename in + // case it contains *, ?, \, etc. + _, name := filepath.Split(path) + escapedName := strings.TrimSuffix(strings.Replace(name, "", "\\", -1), "\\") + if match, _ := doublestar.Match(glob+"/"+escapedName, path); match { + return true + } + } else if match, _ := doublestar.Match(glob, path); match { + return true + } else if isDir { + // Workaround doublestar bug (v4.6.1). + // "foo*/**" should match "foo", but does not, + // because isZeroLengthPattern does not accept + // "*/**" as a zero length pattern. + if trunc := strings.TrimSuffix(glob, "*/**"); trunc != glob { + if match, _ := doublestar.Match(trunc, path); match { + return true + } + } + } + } + return false +} + +// Delete entries from cp.files that do not match cp.globs. +// +// Delete entries from cp.dirs that do not match cp.globs. +// +// Ensure parent/ancestor directories of remaining cp.files and +// cp.dirs entries are still present in cp.dirs, even if they do not +// match cp.globs themselves. +func (cp *copier) applyGlobsToFilesAndDirs() { + if len(cp.globs) == 0 { + return + } + keepdirs := make(map[string]bool) + for _, path := range cp.dirs { + if cp.matchGlobs(path, true) { + keepdirs[path] = true + } + } + for path := range keepdirs { + for i, c := range path { + if i > 0 && c == '/' { + keepdirs[path[:i]] = true + } + } + } + var keepfiles []filetodo + for _, file := range cp.files { + if cp.matchGlobs(file.dst, false) { + keepfiles = append(keepfiles, file) + } + } + for _, file := range keepfiles { + for i, c := range file.dst { + if i > 0 && c == '/' { + keepdirs[file.dst[:i]] = true + } + } + } + cp.dirs = nil + for path := range keepdirs { + cp.dirs = append(cp.dirs, path) + } + sort.Strings(cp.dirs) + cp.files = keepfiles +} + +// Delete files in collfs that do not match cp.globs. Also delete +// directories that are empty (after deleting non-matching files) and +// do not match cp.globs themselves. +func (cp *copier) applyGlobsToCollectionFS(collfs arvados.CollectionFileSystem) error { + if len(cp.globs) == 0 { + return nil + } + include := make(map[string]bool) + err := fs.WalkDir(arvados.FS(collfs), "", func(path string, ent fs.DirEntry, err error) error { + if cp.matchGlobs(path, ent.IsDir()) { + for i, c := range path { + if i > 0 && c == '/' { + include[path[:i]] = true + } + } + include[path] = true + } + return nil + }) + if err != nil { + return err + } + err = fs.WalkDir(arvados.FS(collfs), "", func(path string, ent fs.DirEntry, err error) error { + if err != nil || path == "" { + return err + } + if !include[path] { + err := collfs.RemoveAll(path) + if err != nil { + return err + } + if ent.IsDir() { + return fs.SkipDir + } + } + return nil + }) + return err +} + +// Return true if it's possible for any descendant of the given path +// to match anything in cp.globs. Used by walkMount to avoid loading +// collections that are mounted underneath ctrOutputPath but excluded +// by globs. +func (cp *copier) subtreeCouldMatch(path string) bool { + if len(cp.globs) == 0 { + return true + } + pathdepth := 1 + strings.Count(path, "/") + for _, glob := range cp.globs { + globdepth := 0 + lastsep := 0 + for i, c := range glob { + if c != '/' || !doublestar.ValidatePattern(glob[:i]) { + // Escaped "/", or "/" in a character + // class, is not a path separator. + continue + } + if glob[lastsep:i] == "**" { + return true + } + lastsep = i + 1 + if globdepth++; globdepth == pathdepth { + if match, _ := doublestar.Match(glob[:i]+"/*", path+"/z"); match { + return true + } + break + } + } + if globdepth < pathdepth && glob[lastsep:] == "**" { + return true + } + } + return false } func (cp *copier) copyFile(fs arvados.CollectionFileSystem, f filetodo) (int64, error) { @@ -161,9 +341,8 @@ func (cp *copier) walkMount(dest, src string, maxSymlinks int, walkMountsBelow b // copy, relative to its mount point -- ".", "./foo.txt", ... srcRelPath := filepath.Join(".", srcMount.Path, src[len(srcRoot):]) - // outputRelPath is the path relative in the output directory - // that corresponds to the path in the output collection where - // the file will go, for logging + // outputRelPath is the destination path relative to the + // output directory. Used for logging and glob matching. var outputRelPath = "" if strings.HasPrefix(src, cp.ctrOutputDir) { outputRelPath = strings.TrimPrefix(src[len(cp.ctrOutputDir):], "/") @@ -177,6 +356,9 @@ func (cp *copier) walkMount(dest, src string, maxSymlinks int, walkMountsBelow b switch { case srcMount.ExcludeFromOutput: + case outputRelPath != "*" && !cp.subtreeCouldMatch(outputRelPath): + cp.logger.Printf("not copying %q because contents cannot match output globs", outputRelPath) + return nil case srcMount.Kind == "tmp": // Handle by walking the host filesystem. return cp.walkHostFS(dest, src, maxSymlinks, walkMountsBelow) @@ -328,6 +510,8 @@ func (cp *copier) walkHostFS(dest, src string, maxSymlinks int, includeMounts bo // (...except mount types that are // handled as regular files.) continue + } else if isMount && !cp.subtreeCouldMatch(src[len(cp.ctrOutputDir)+1:]) { + continue } err = cp.walkHostFS(dest, src, maxSymlinks, false) if err != nil { diff --git a/lib/crunchrun/copier_test.go b/lib/crunchrun/copier_test.go index c8936d1a9f..486bf6fa63 100644 --- a/lib/crunchrun/copier_test.go +++ b/lib/crunchrun/copier_test.go @@ -7,8 +7,9 @@ package crunchrun import ( "bytes" "io" - "io/ioutil" + "io/fs" "os" + "sort" "syscall" "git.arvados.org/arvados.git/sdk/go/arvados" @@ -115,9 +116,7 @@ func (s *copierSuite) TestSymlinkToMountedCollection(c *check.C) { } // simulate mounted writable collection - bindtmp, err := ioutil.TempDir("", "crunch-run.test.") - c.Assert(err, check.IsNil) - defer os.RemoveAll(bindtmp) + bindtmp := c.MkDir() f, err := os.OpenFile(bindtmp+"/.arvados#collection", os.O_CREATE|os.O_WRONLY, 0644) c.Assert(err, check.IsNil) _, err = io.WriteString(f, `{"manifest_text":". 37b51d194a7513e45b56f6524f2d51f2+3 0:3:bar\n"}`) @@ -215,6 +214,142 @@ func (s *copierSuite) TestWritableMountBelow(c *check.C) { }) } +// Check some glob-matching edge cases. In particular, check that +// patterns like "foo/**" do not match regular files named "foo" +// (unless of course they are inside a directory named "foo"). +func (s *copierSuite) TestMatchGlobs(c *check.C) { + s.cp.globs = []string{"foo*/**"} + c.Check(s.cp.matchGlobs("foo", true), check.Equals, true) + c.Check(s.cp.matchGlobs("food", true), check.Equals, true) + c.Check(s.cp.matchGlobs("foo", false), check.Equals, false) + c.Check(s.cp.matchGlobs("food", false), check.Equals, false) + c.Check(s.cp.matchGlobs("foo/bar", false), check.Equals, true) + c.Check(s.cp.matchGlobs("food/bar", false), check.Equals, true) + c.Check(s.cp.matchGlobs("foo/bar", true), check.Equals, true) + c.Check(s.cp.matchGlobs("food/bar", true), check.Equals, true) + + s.cp.globs = []string{"ba[!/]/foo*/**"} + c.Check(s.cp.matchGlobs("bar/foo", true), check.Equals, true) + c.Check(s.cp.matchGlobs("bar/food", true), check.Equals, true) + c.Check(s.cp.matchGlobs("bar/foo", false), check.Equals, false) + c.Check(s.cp.matchGlobs("bar/food", false), check.Equals, false) + c.Check(s.cp.matchGlobs("bar/foo/z\\[", true), check.Equals, true) + c.Check(s.cp.matchGlobs("bar/food/z\\[", true), check.Equals, true) + c.Check(s.cp.matchGlobs("bar/foo/z\\[", false), check.Equals, true) + c.Check(s.cp.matchGlobs("bar/food/z\\[", false), check.Equals, true) + + s.cp.globs = []string{"waz/**/foo*/**"} + c.Check(s.cp.matchGlobs("waz/quux/foo", true), check.Equals, true) + c.Check(s.cp.matchGlobs("waz/quux/food", true), check.Equals, true) + c.Check(s.cp.matchGlobs("waz/quux/foo", false), check.Equals, false) + c.Check(s.cp.matchGlobs("waz/quux/food", false), check.Equals, false) + c.Check(s.cp.matchGlobs("waz/quux/foo/foo", true), check.Equals, true) + c.Check(s.cp.matchGlobs("waz/quux/food/foo", true), check.Equals, true) + c.Check(s.cp.matchGlobs("waz/quux/foo/foo", false), check.Equals, true) + c.Check(s.cp.matchGlobs("waz/quux/food/foo", false), check.Equals, true) + + s.cp.globs = []string{"foo/**/*"} + c.Check(s.cp.matchGlobs("foo", false), check.Equals, false) + c.Check(s.cp.matchGlobs("foo/bar", false), check.Equals, true) + c.Check(s.cp.matchGlobs("foo/bar/baz", false), check.Equals, true) + c.Check(s.cp.matchGlobs("foo/bar/baz/waz", false), check.Equals, true) +} + +func (s *copierSuite) TestSubtreeCouldMatch(c *check.C) { + for _, trial := range []struct { + mount string // relative to output dir + glob string + could bool + }{ + {mount: "abc", glob: "*"}, + {mount: "abc", glob: "abc/*", could: true}, + {mount: "abc", glob: "a*/**", could: true}, + {mount: "abc", glob: "**", could: true}, + {mount: "abc", glob: "*/*", could: true}, + {mount: "abc", glob: "**/*.txt", could: true}, + {mount: "abc/def", glob: "*"}, + {mount: "abc/def", glob: "*/*"}, + {mount: "abc/def", glob: "*/*.txt"}, + {mount: "abc/def", glob: "*/*/*", could: true}, + {mount: "abc/def", glob: "**", could: true}, + {mount: "abc/def", glob: "**/bar", could: true}, + {mount: "abc/def", glob: "abc/**", could: true}, + {mount: "abc/def/ghi", glob: "*c/**/bar", could: true}, + {mount: "abc/def/ghi", glob: "*c/*f/bar"}, + {mount: "abc/def/ghi", glob: "abc/d[^/]f/ghi/*", could: true}, + } { + c.Logf("=== %+v", trial) + got := (&copier{ + globs: []string{trial.glob}, + }).subtreeCouldMatch(trial.mount) + c.Check(got, check.Equals, trial.could) + } +} + +func (s *copierSuite) TestMountBelowExcludedByGlob(c *check.C) { + bindtmp := c.MkDir() + s.cp.mounts["/ctr/outdir/include/includer"] = arvados.Mount{ + Kind: "collection", + PortableDataHash: arvadostest.FooCollectionPDH, + } + s.cp.mounts["/ctr/outdir/include/includew"] = arvados.Mount{ + Kind: "collection", + PortableDataHash: arvadostest.FooCollectionPDH, + Writable: true, + } + s.cp.mounts["/ctr/outdir/exclude/excluder"] = arvados.Mount{ + Kind: "collection", + PortableDataHash: arvadostest.FooCollectionPDH, + } + s.cp.mounts["/ctr/outdir/exclude/excludew"] = arvados.Mount{ + Kind: "collection", + PortableDataHash: arvadostest.FooCollectionPDH, + Writable: true, + } + s.cp.mounts["/ctr/outdir/nonexistent/collection"] = arvados.Mount{ + // As extra assurance, plant a collection that will + // fail if copier attempts to load its manifest. (For + // performance reasons it's important that copier + // doesn't try to load the manifest before deciding + // not to copy the contents.) + Kind: "collection", + PortableDataHash: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+1234", + } + s.cp.globs = []string{ + "?ncl*/*r/*", + "*/?ncl*/**", + } + c.Assert(os.MkdirAll(s.cp.hostOutputDir+"/include/includer", 0755), check.IsNil) + c.Assert(os.MkdirAll(s.cp.hostOutputDir+"/include/includew", 0755), check.IsNil) + c.Assert(os.MkdirAll(s.cp.hostOutputDir+"/exclude/excluder", 0755), check.IsNil) + c.Assert(os.MkdirAll(s.cp.hostOutputDir+"/exclude/excludew", 0755), check.IsNil) + s.writeFileInOutputDir(c, "include/includew/foo", "foo") + s.writeFileInOutputDir(c, "exclude/excludew/foo", "foo") + s.cp.bindmounts = map[string]bindmount{ + "/ctr/outdir/include/includew": bindmount{HostPath: bindtmp, ReadOnly: false}, + } + s.cp.bindmounts = map[string]bindmount{ + "/ctr/outdir/include/excludew": bindmount{HostPath: bindtmp, ReadOnly: false}, + } + + err := s.cp.walkMount("", s.cp.ctrOutputDir, 10, true) + c.Check(err, check.IsNil) + c.Log(s.log.String()) + + // Note it's OK that "/exclude" is not excluded by walkMount: + // it is just a local filesystem directory, not a mount point + // that's expensive to walk. In real-life usage, it will be + // removed from cp.dirs before any copying happens. + c.Check(s.cp.dirs, check.DeepEquals, []string{"/exclude", "/include", "/include/includew"}) + c.Check(s.cp.files, check.DeepEquals, []filetodo{ + {src: s.cp.hostOutputDir + "/include/includew/foo", dst: "/include/includew/foo", size: 3}, + }) + c.Check(s.cp.manifest, check.Matches, `(?ms).*\./include/includer .*`) + c.Check(s.cp.manifest, check.Not(check.Matches), `(?ms).*exclude.*`) + c.Check(s.log.String(), check.Matches, `(?ms).*not copying \\"exclude/excluder\\".*`) + c.Check(s.log.String(), check.Matches, `(?ms).*not copying \\"nonexistent/collection\\".*`) +} + func (s *copierSuite) writeFileInOutputDir(c *check.C, path, data string) { f, err := os.OpenFile(s.cp.hostOutputDir+"/"+path, os.O_CREATE|os.O_WRONLY, 0644) c.Assert(err, check.IsNil) @@ -222,3 +357,184 @@ func (s *copierSuite) writeFileInOutputDir(c *check.C, path, data string) { c.Assert(err, check.IsNil) c.Assert(f.Close(), check.IsNil) } + +// applyGlobsToFilesAndDirs uses the same glob-matching code as +// applyGlobsToCollectionFS, so we don't need to test all of the same +// glob-matching behavior covered in TestApplyGlobsToCollectionFS. We +// do need to check that (a) the glob is actually being used to filter +// out files, and (b) non-matching dirs still included if and only if +// they are ancestors of matching files. +func (s *copierSuite) TestApplyGlobsToFilesAndDirs(c *check.C) { + dirs := []string{"dir1", "dir1/dir11", "dir1/dir12", "dir2"} + files := []string{"dir1/file11", "dir1/dir11/file111", "dir2/file2"} + for _, trial := range []struct { + globs []string + dirs []string + files []string + }{ + { + globs: []string{}, + dirs: append([]string{}, dirs...), + files: append([]string{}, files...), + }, + { + globs: []string{"**"}, + dirs: append([]string{}, dirs...), + files: append([]string{}, files...), + }, + { + globs: []string{"**/file111"}, + dirs: []string{"dir1", "dir1/dir11"}, + files: []string{"dir1/dir11/file111"}, + }, + { + globs: []string{"nothing"}, + dirs: nil, + files: nil, + }, + { + globs: []string{"**/dir12"}, + dirs: []string{"dir1", "dir1/dir12"}, + files: nil, + }, + { + globs: []string{"**/file*"}, + dirs: []string{"dir1", "dir1/dir11", "dir2"}, + files: append([]string{}, files...), + }, + { + globs: []string{"**/dir1[12]"}, + dirs: []string{"dir1", "dir1/dir11", "dir1/dir12"}, + files: nil, + }, + { + globs: []string{"**/dir1[^2]"}, + dirs: []string{"dir1", "dir1/dir11"}, + files: nil, + }, + { + globs: []string{"dir1/**"}, + dirs: []string{"dir1", "dir1/dir11", "dir1/dir12"}, + files: []string{"dir1/file11", "dir1/dir11/file111"}, + }, + } { + c.Logf("=== globs: %q", trial.globs) + cp := copier{ + globs: trial.globs, + dirs: dirs, + } + for _, path := range files { + cp.files = append(cp.files, filetodo{dst: path}) + } + cp.applyGlobsToFilesAndDirs() + var gotFiles []string + for _, file := range cp.files { + gotFiles = append(gotFiles, file.dst) + } + c.Check(cp.dirs, check.DeepEquals, trial.dirs) + c.Check(gotFiles, check.DeepEquals, trial.files) + } +} + +func (s *copierSuite) TestApplyGlobsToCollectionFS(c *check.C) { + for _, trial := range []struct { + globs []string + expect []string + }{ + { + globs: nil, + expect: []string{"foo", "bar", "baz/quux", "baz/parent1/item1"}, + }, + { + globs: []string{"foo"}, + expect: []string{"foo"}, + }, + { + globs: []string{"baz/parent1/item1"}, + expect: []string{"baz/parent1/item1"}, + }, + { + globs: []string{"**"}, + expect: []string{"foo", "bar", "baz/quux", "baz/parent1/item1"}, + }, + { + globs: []string{"**/*"}, + expect: []string{"foo", "bar", "baz/quux", "baz/parent1/item1"}, + }, + { + globs: []string{"*"}, + expect: []string{"foo", "bar"}, + }, + { + globs: []string{"baz"}, + expect: nil, + }, + { + globs: []string{"b*/**"}, + expect: []string{"baz/quux", "baz/parent1/item1"}, + }, + { + globs: []string{"baz"}, + expect: nil, + }, + { + globs: []string{"baz/**"}, + expect: []string{"baz/quux", "baz/parent1/item1"}, + }, + { + globs: []string{"baz/*"}, + expect: []string{"baz/quux"}, + }, + { + globs: []string{"baz/**/*uu?"}, + expect: []string{"baz/quux"}, + }, + { + globs: []string{"**/*m1"}, + expect: []string{"baz/parent1/item1"}, + }, + { + globs: []string{"*/*/*/**/*1"}, + expect: nil, + }, + { + globs: []string{"f*", "**/q*"}, + expect: []string{"foo", "baz/quux"}, + }, + { + globs: []string{"\\"}, // invalid pattern matches nothing + expect: nil, + }, + { + globs: []string{"\\", "foo"}, + expect: []string{"foo"}, + }, + { + globs: []string{"foo/**"}, + expect: nil, + }, + { + globs: []string{"foo*/**"}, + expect: nil, + }, + } { + c.Logf("=== globs: %q", trial.globs) + collfs, err := (&arvados.Collection{ManifestText: ". d41d8cd98f00b204e9800998ecf8427e+0 0:0:foo 0:0:bar 0:0:baz/quux 0:0:baz/parent1/item1\n"}).FileSystem(nil, nil) + c.Assert(err, check.IsNil) + cp := copier{globs: trial.globs} + err = cp.applyGlobsToCollectionFS(collfs) + if !c.Check(err, check.IsNil) { + continue + } + var got []string + fs.WalkDir(arvados.FS(collfs), "", func(path string, ent fs.DirEntry, err error) error { + if !ent.IsDir() { + got = append(got, path) + } + return nil + }) + sort.Strings(got) + sort.Strings(trial.expect) + c.Check(got, check.DeepEquals, trial.expect) + } +} diff --git a/lib/crunchrun/crunchrun.go b/lib/crunchrun/crunchrun.go index 556a3bfe13..8627045411 100644 --- a/lib/crunchrun/crunchrun.go +++ b/lib/crunchrun/crunchrun.go @@ -81,9 +81,6 @@ type IKeepClient interface { SetStorageClasses(sc []string) } -// NewLogWriter is a factory function to create a new log writer. -type NewLogWriter func(name string) (io.WriteCloser, error) - type RunArvMount func(cmdline []string, tok string) (*exec.Cmd, error) type MkTempDir func(string, string) (string, error) @@ -125,8 +122,7 @@ type ContainerRunner struct { Container arvados.Container token string ExitCode *int - NewLogWriter NewLogWriter - CrunchLog *ThrottledLogger + CrunchLog *logWriter logUUID string logMtx sync.Mutex LogCollection arvados.CollectionFileSystem @@ -168,7 +164,7 @@ type ContainerRunner struct { enableNetwork string // one of "default" or "always" networkMode string // "none", "host", or "" -- passed through to executor brokenNodeHook string // script to run if node appears to be broken - arvMountLog *ThrottledLogger + arvMountLog io.WriteCloser containerWatchdogInterval time.Duration @@ -303,11 +299,10 @@ func (runner *ContainerRunner) ArvMountCmd(cmdline []string, token string) (c *e } c.Env = append(c.Env, "ARVADOS_API_TOKEN="+token) - w, err := runner.NewLogWriter("arv-mount") + runner.arvMountLog, err = runner.openLogFile("arv-mount") if err != nil { return nil, err } - runner.arvMountLog = NewThrottledLogger(w) scanner := logScanner{ Patterns: []string{ "Keep write error", @@ -626,17 +621,6 @@ func (runner *ContainerRunner) SetupMounts() (map[string]bindmount, error) { // OutputPath is a staging directory. bindmounts[bind] = bindmount{HostPath: tmpfn, ReadOnly: true} } - - case mnt.Kind == "git_tree": - tmpdir, err := runner.MkTempDir(runner.parentTemp, "git_tree") - if err != nil { - return nil, fmt.Errorf("creating temp dir: %v", err) - } - err = gitMount(mnt).extractTree(runner.containerClient, tmpdir, token) - if err != nil { - return nil, err - } - bindmounts[bind] = bindmount{HostPath: tmpdir, ReadOnly: true} } } @@ -746,13 +730,13 @@ func (runner *ContainerRunner) stopHoststat() error { } func (runner *ContainerRunner) startHoststat() error { - w, err := runner.NewLogWriter("hoststat") + var err error + runner.hoststatLogger, err = runner.openLogFile("hoststat") if err != nil { return err } - runner.hoststatLogger = NewThrottledLogger(w) runner.hoststatReporter = &crunchstat.Reporter{ - Logger: log.New(runner.hoststatLogger, "", 0), + Logger: newLogWriter(runner.hoststatLogger), // Our own cgroup is the "host" cgroup, in the sense // that it accounts for resource usage outside the // container. It doesn't count _all_ resource usage on @@ -770,15 +754,15 @@ func (runner *ContainerRunner) startHoststat() error { } func (runner *ContainerRunner) startCrunchstat() error { - w, err := runner.NewLogWriter("crunchstat") + var err error + runner.statLogger, err = runner.openLogFile("crunchstat") if err != nil { return err } - runner.statLogger = NewThrottledLogger(w) runner.statReporter = &crunchstat.Reporter{ Pid: runner.executor.Pid, FS: runner.crunchstatFakeFS, - Logger: log.New(runner.statLogger, "", 0), + Logger: newLogWriter(runner.statLogger), MemThresholds: map[string][]crunchstat.Threshold{ "rss": crunchstat.NewThresholdsFromPercentages(runner.Container.RuntimeConstraints.RAM, []int64{90, 95, 99}), }, @@ -801,7 +785,7 @@ type infoCommand struct { // might differ from what's described in the node record (see // LogNodeRecord). func (runner *ContainerRunner) LogHostInfo() (err error) { - w, err := runner.NewLogWriter("node-info") + w, err := runner.openLogFile("node-info") if err != nil { return } @@ -852,62 +836,40 @@ func (runner *ContainerRunner) LogHostInfo() (err error) { // LogContainerRecord gets and saves the raw JSON container record from the API server func (runner *ContainerRunner) LogContainerRecord() error { - logged, err := runner.logAPIResponse("container", "containers", map[string]interface{}{"filters": [][]string{{"uuid", "=", runner.Container.UUID}}}, nil) + logged, err := runner.logAPIResponse("container", "containers", map[string]interface{}{"filters": [][]string{{"uuid", "=", runner.Container.UUID}}}) if !logged && err == nil { err = fmt.Errorf("error: no container record found for %s", runner.Container.UUID) } return err } -// LogNodeRecord logs the current host's InstanceType config entry (or -// the arvados#node record, if running via crunch-dispatch-slurm). +// LogNodeRecord logs the current host's InstanceType config entry, if +// running via arvados-dispatch-cloud. func (runner *ContainerRunner) LogNodeRecord() error { - if it := os.Getenv("InstanceType"); it != "" { - // Dispatched via arvados-dispatch-cloud. Save - // InstanceType config fragment received from - // dispatcher on stdin. - w, err := runner.LogCollection.OpenFile("node.json", os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - return err - } - defer w.Close() - _, err = io.WriteString(w, it) - if err != nil { - return err - } - return w.Close() + it := os.Getenv("InstanceType") + if it == "" { + // Not dispatched by arvados-dispatch-cloud. + return nil + } + // Save InstanceType config fragment received from dispatcher + // on stdin. + w, err := runner.LogCollection.OpenFile("node.json", os.O_CREATE|os.O_WRONLY, 0666) + if err != nil { + return err } - // Dispatched via crunch-dispatch-slurm. Look up - // apiserver's node record corresponding to - // $SLURMD_NODENAME. - hostname := os.Getenv("SLURMD_NODENAME") - if hostname == "" { - hostname, _ = os.Hostname() + defer w.Close() + _, err = io.WriteString(w, it) + if err != nil { + return err } - _, err := runner.logAPIResponse("node", "nodes", map[string]interface{}{"filters": [][]string{{"hostname", "=", hostname}}}, func(resp interface{}) { - // The "info" field has admin-only info when - // obtained with a privileged token, and - // should not be logged. - node, ok := resp.(map[string]interface{}) - if ok { - delete(node, "info") - } - }) - return err + return w.Close() } -func (runner *ContainerRunner) logAPIResponse(label, path string, params map[string]interface{}, munge func(interface{})) (logged bool, err error) { +func (runner *ContainerRunner) logAPIResponse(label, path string, params map[string]interface{}) (logged bool, err error) { writer, err := runner.LogCollection.OpenFile(label+".json", os.O_CREATE|os.O_WRONLY, 0666) if err != nil { return false, err } - w := &ArvLogWriter{ - ArvClient: runner.DispatcherArvClient, - UUID: runner.Container.UUID, - loggingStream: label, - writeCloser: writer, - } - reader, err := runner.DispatcherArvClient.CallRaw("GET", path, "", "", arvadosclient.Dict(params)) if err != nil { return false, fmt.Errorf("error getting %s record: %v", label, err) @@ -926,16 +888,13 @@ func (runner *ContainerRunner) logAPIResponse(label, path string, params map[str } else if len(items) < 1 { return false, nil } - if munge != nil { - munge(items[0]) - } // Re-encode it using indentation to improve readability - enc := json.NewEncoder(w) + enc := json.NewEncoder(writer) enc.SetIndent("", " ") if err = enc.Encode(items[0]); err != nil { return false, fmt.Errorf("error logging %s record: %v", label, err) } - err = w.Close() + err = writer.Close() if err != nil { return false, fmt.Errorf("error closing %s.json in log collection: %v", label, err) } @@ -1003,10 +962,10 @@ func (runner *ContainerRunner) CreateContainer(imageID string, bindmounts map[st return err } stdout = f - } else if w, err := runner.NewLogWriter("stdout"); err != nil { + } else if w, err := runner.openLogFile("stdout"); err != nil { return err } else { - stdout = NewThrottledLogger(w) + stdout = w } if mnt, ok := runner.Container.Mounts["stderr"]; ok { @@ -1015,10 +974,10 @@ func (runner *ContainerRunner) CreateContainer(imageID string, bindmounts map[st return err } stderr = f - } else if w, err := runner.NewLogWriter("stderr"); err != nil { + } else if w, err := runner.openLogFile("stderr"); err != nil { return err } else { - stderr = NewThrottledLogger(w) + stderr = w } env := runner.Container.Environment @@ -1365,6 +1324,7 @@ func (runner *ContainerRunner) CaptureOutput(bindmounts map[string]bindmount) er keepClient: runner.ContainerKeepClient, hostOutputDir: runner.HostOutputDir, ctrOutputDir: runner.Container.OutputPath, + globs: runner.Container.OutputGlob, bindmounts: bindmounts, mounts: runner.Container.Mounts, secretMounts: runner.SecretMounts, @@ -1470,19 +1430,11 @@ func (runner *ContainerRunner) CommitLogs() error { if runner.arvMountLog != nil { runner.arvMountLog.Close() } - runner.CrunchLog.Close() - - // Closing CrunchLog above allows them to be committed to Keep at this - // point, but re-open crunch log with ArvClient in case there are any - // other further errors (such as failing to write the log to Keep!) - // while shutting down - runner.CrunchLog = NewThrottledLogger(&ArvLogWriter{ - ArvClient: runner.DispatcherArvClient, - UUID: runner.Container.UUID, - loggingStream: "crunch-run", - writeCloser: nil, - }) - runner.CrunchLog.Immediate = log.New(os.Stderr, runner.Container.UUID+" ", 0) + + // From now on just log to stderr, in case there are + // any other further errors (such as failing to write + // the log to Keep!) while shutting down + runner.CrunchLog = newLogWriter(newTimestamper(newStringPrefixer(os.Stderr, runner.Container.UUID+" "))) }() if runner.keepstoreLogger != nil { @@ -1642,18 +1594,8 @@ func (runner *ContainerRunner) IsCancelled() bool { return runner.cCancelled } -// NewArvLogWriter creates an ArvLogWriter -func (runner *ContainerRunner) NewArvLogWriter(name string) (io.WriteCloser, error) { - writer, err := runner.LogCollection.OpenFile(name+".txt", os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - return nil, err - } - return &ArvLogWriter{ - ArvClient: runner.DispatcherArvClient, - UUID: runner.Container.UUID, - loggingStream: name, - writeCloser: writer, - }, nil +func (runner *ContainerRunner) openLogFile(name string) (io.WriteCloser, error) { + return runner.LogCollection.OpenFile(name+".txt", os.O_CREATE|os.O_WRONLY, 0666) } // Run the full container lifecycle. @@ -1683,9 +1625,7 @@ func (runner *ContainerRunner) Run() (err error) { defer func() { runner.CleanupDirs() - runner.CrunchLog.Printf("crunch-run finished") - runner.CrunchLog.Close() }() err = runner.fetchContainerRecord() @@ -1879,7 +1819,6 @@ func NewContainerRunner(dispatcherClient *arvados.Client, DispatcherArvClient: dispatcherArvClient, DispatcherKeepClient: dispatcherKeepClient, } - cr.NewLogWriter = cr.NewArvLogWriter cr.RunArvMount = cr.ArvMountCmd cr.MkTempDir = ioutil.TempDir cr.MkArvClient = func(token string) (IArvadosClient, IKeepClient, *arvados.Client, error) { @@ -1902,14 +1841,12 @@ func NewContainerRunner(dispatcherClient *arvados.Client, return nil, err } cr.Container.UUID = containerUUID - w, err := cr.NewLogWriter("crunch-run") + f, err := cr.openLogFile("crunch-run") if err != nil { return nil, err } - cr.CrunchLog = NewThrottledLogger(w) - cr.CrunchLog.Immediate = log.New(os.Stderr, containerUUID+" ", 0) + cr.CrunchLog = newLogWriter(newTimestamper(io.MultiWriter(f, newStringPrefixer(os.Stderr, cr.Container.UUID+" ")))) - loadLogThrottleParams(dispatcherArvClient) go cr.updateLogs() return cr, nil @@ -2054,12 +1991,11 @@ func (command) RunCommand(prog string, args []string, stdin io.Reader, stdout, s keepstoreLogbuf.SetWriter(io.Discard) } else { cr.CrunchLog.Printf("using local keepstore process (pid %d) at %s, writing logs to keepstore.txt in log collection", keepstore.Process.Pid, os.Getenv("ARVADOS_KEEP_SERVICES")) - logwriter, err := cr.NewLogWriter("keepstore") + cr.keepstoreLogger, err = cr.openLogFile("keepstore") if err != nil { log.Print(err) return 1 } - cr.keepstoreLogger = NewThrottledLogger(logwriter) var writer io.WriteCloser = cr.keepstoreLogger if logWhat == "errors" { @@ -2085,13 +2021,11 @@ func (command) RunCommand(prog string, args []string, stdin io.Reader, stdout, s cr.executor, err = newSingularityExecutor(cr.CrunchLog.Printf) default: cr.CrunchLog.Printf("%s: unsupported RuntimeEngine %q", containerUUID, *runtimeEngine) - cr.CrunchLog.Close() return 1 } if err != nil { cr.CrunchLog.Printf("%s: %v", containerUUID, err) cr.checkBrokenNode(err) - cr.CrunchLog.Close() return 1 } defer cr.executor.Close() diff --git a/lib/crunchrun/crunchrun_test.go b/lib/crunchrun/crunchrun_test.go index 276dd36661..e51dfe629b 100644 --- a/lib/crunchrun/crunchrun_test.go +++ b/lib/crunchrun/crunchrun_test.go @@ -12,8 +12,8 @@ import ( "errors" "fmt" "io" + "io/fs" "io/ioutil" - "log" "math/rand" "net/http" "net/http/httptest" @@ -39,8 +39,6 @@ import ( "git.arvados.org/arvados.git/sdk/go/manifest" . "gopkg.in/check.v1" - git_client "gopkg.in/src-d/go-git.v4/plumbing/transport/client" - git_http "gopkg.in/src-d/go-git.v4/plumbing/transport/http" ) // Gocheck boilerplate @@ -113,6 +111,7 @@ func (s *TestSuite) SetUpTest(c *C) { err = ioutil.WriteFile(s.keepmount+"/by_id/"+fakeInputCollectionPDH+"/input.json", []byte(`{"input":true}`), 0644) c.Assert(err, IsNil) s.runner.ArvMountPoint = s.keepmount + os.Setenv("InstanceType", `{"ProviderType":"a1.2xlarge","Price":1.2}`) } type ArvTestClient struct { @@ -121,7 +120,6 @@ type ArvTestClient struct { Content []arvadosclient.Dict arvados.Container secretMounts []byte - Logs map[string]*bytes.Buffer sync.Mutex WasSetRunning bool callraw bool @@ -129,8 +127,8 @@ type ArvTestClient struct { type KeepTestClient struct { Called bool - Content []byte StorageClasses []string + blocks sync.Map } type stubExecutor struct { @@ -207,14 +205,7 @@ func (client *ArvTestClient) Create(resourceType string, client.Content = append(client.Content, parameters) if resourceType == "logs" { - et := parameters["log"].(arvadosclient.Dict)["event_type"].(string) - if client.Logs == nil { - client.Logs = make(map[string]*bytes.Buffer) - } - if client.Logs[et] == nil { - client.Logs[et] = &bytes.Buffer{} - } - client.Logs[et].Write([]byte(parameters["log"].(arvadosclient.Dict)["properties"].(map[string]string)["text"])) + panic("logs.create called") } if resourceType == "collections" && output != nil { @@ -311,20 +302,14 @@ func (client *ArvTestClient) Update(resourceType string, uuid string, parameters } else if resourceType == "collections" && output != nil { mt := parameters["collection"].(arvadosclient.Dict)["manifest_text"].(string) output.(*arvados.Collection).UUID = uuid - output.(*arvados.Collection).PortableDataHash = fmt.Sprintf("%x", md5.Sum([]byte(mt))) + output.(*arvados.Collection).PortableDataHash = arvados.PortableDataHash(mt) } return nil } var discoveryMap = map[string]interface{}{ - "defaultTrashLifetime": float64(1209600), - "crunchLimitLogBytesPerJob": float64(67108864), - "crunchLogThrottleBytes": float64(65536), - "crunchLogThrottlePeriod": float64(60), - "crunchLogThrottleLines": float64(1024), - "crunchLogPartialLineThrottlePeriod": float64(5), - "crunchLogBytesPerEvent": float64(4096), - "crunchLogSecondsBetweenEvents": float64(1), + "crunchLogUpdateSize": float64(crunchLogUpdateSize), + "crunchLogUpdatePeriod": float64(crunchLogUpdatePeriod.Seconds()), } func (client *ArvTestClient) Discovery(key string) (interface{}, error) { @@ -358,18 +343,30 @@ func (client *KeepTestClient) LocalLocator(locator string) (string, error) { } func (client *KeepTestClient) BlockWrite(_ context.Context, opts arvados.BlockWriteOptions) (arvados.BlockWriteResponse, error) { - client.Content = opts.Data + locator := fmt.Sprintf("%x+%d", md5.Sum(opts.Data), len(opts.Data)) + client.blocks.Store(locator, append([]byte(nil), opts.Data...)) return arvados.BlockWriteResponse{ - Locator: fmt.Sprintf("%x+%d", md5.Sum(opts.Data), len(opts.Data)), + Locator: locator, }, nil } -func (client *KeepTestClient) ReadAt(string, []byte, int) (int, error) { - return 0, errors.New("not implemented") +func (client *KeepTestClient) ReadAt(locator string, dst []byte, offset int) (int, error) { + loaded, ok := client.blocks.Load(locator) + if !ok { + return 0, os.ErrNotExist + } + data := loaded.([]byte) + if offset >= len(data) { + return 0, io.EOF + } + return copy(dst, data[offset:]), nil } func (client *KeepTestClient) Close() { - client.Content = nil + client.blocks.Range(func(locator, value interface{}) bool { + client.blocks.Delete(locator) + return true + }) } func (client *KeepTestClient) SetStorageClasses(sc []string) { @@ -591,33 +588,10 @@ func (ErrorReader) Seek(int64, int) (int64, error) { return 0, errors.New("ErrorReader") } -func (KeepReadErrorTestClient) ManifestFileReader(m manifest.Manifest, filename string) (arvados.File, error) { +func (*KeepReadErrorTestClient) ManifestFileReader(m manifest.Manifest, filename string) (arvados.File, error) { return ErrorReader{}, nil } -type ClosableBuffer struct { - bytes.Buffer -} - -func (*ClosableBuffer) Close() error { - return nil -} - -type TestLogs struct { - Stdout ClosableBuffer - Stderr ClosableBuffer -} - -func (tl *TestLogs) NewTestLoggingWriter(logstr string) (io.WriteCloser, error) { - if logstr == "stdout" { - return &tl.Stdout, nil - } - if logstr == "stderr" { - return &tl.Stderr, nil - } - return nil, errors.New("???") -} - func dockerLog(fd byte, msg string) []byte { by := []byte(msg) header := make([]byte, 8+len(by)) @@ -633,8 +607,6 @@ func (s *TestSuite) TestRunContainer(c *C) { return 0 } - var logs TestLogs - s.runner.NewLogWriter = logs.NewTestLoggingWriter s.runner.Container.ContainerImage = arvadostest.DockerImage112PDH s.runner.Container.Command = []string{"./hw"} s.runner.Container.OutputStorageClasses = []string{"default"} @@ -651,8 +623,8 @@ func (s *TestSuite) TestRunContainer(c *C) { err = s.runner.WaitFinish() c.Assert(err, IsNil) - c.Check(logs.Stdout.String(), Matches, ".*Hello world\n") - c.Check(logs.Stderr.String(), Equals, "") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, `Hello world\n`) + c.Check(logFileContent(c, s.runner, "stderr.txt"), Matches, ``) } func (s *TestSuite) TestCommitLogs(c *C) { @@ -661,7 +633,9 @@ func (s *TestSuite) TestCommitLogs(c *C) { defer kc.Close() cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzz-zzzzzzzzzzzzzzz") c.Assert(err, IsNil) - cr.CrunchLog.Timestamper = (&TestTimestamper{}).Timestamp + f, err := cr.openLogFile("crunch-run") + c.Assert(err, IsNil) + cr.CrunchLog = newLogWriter(newTestTimestamper(f)) cr.CrunchLog.Print("Hello world!") cr.CrunchLog.Print("Goodbye") @@ -670,10 +644,10 @@ func (s *TestSuite) TestCommitLogs(c *C) { err = cr.CommitLogs() c.Check(err, IsNil) - c.Check(api.Calls, Equals, 2) - c.Check(api.Content[1]["ensure_unique_name"], Equals, true) - c.Check(api.Content[1]["collection"].(arvadosclient.Dict)["name"], Equals, "logs for zzzzz-zzzzz-zzzzzzzzzzzzzzz") - c.Check(api.Content[1]["collection"].(arvadosclient.Dict)["manifest_text"], Equals, ". 744b2e4553123b02fa7b452ec5c18993+123 0:123:crunch-run.txt\n") + c.Check(api.Calls, Equals, 1) + c.Check(api.Content[0]["ensure_unique_name"], Equals, true) + c.Check(api.Content[0]["collection"].(arvadosclient.Dict)["name"], Equals, "logs for zzzzz-zzzzz-zzzzzzzzzzzzzzz") + c.Check(api.Content[0]["collection"].(arvadosclient.Dict)["manifest_text"], Equals, ". 744b2e4553123b02fa7b452ec5c18993+123 0:123:crunch-run.txt\n") c.Check(*cr.LogsPDH, Equals, "63da7bdacf08c40f604daad80c261e9a+60") } @@ -794,10 +768,7 @@ func (s *TestSuite) fullRunHelper(c *C, record string, extraMounts []string, fn } if err != nil { - for k, v := range s.api.Logs { - c.Log(k) - c.Log(v.String()) - } + dumpAllLogFiles(c, s.runner) } return s.api, s.runner, realTemp @@ -832,7 +803,7 @@ func (s *TestSuite) TestFullRunHello(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, ".*hello world\n") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, "hello world\n") c.Check(s.testDispatcherKeepClient.StorageClasses, DeepEquals, []string{"default"}) c.Check(s.testContainerKeepClient.StorageClasses, DeepEquals, []string{"default"}) } @@ -905,6 +876,48 @@ func (s *TestSuite) testSpotInterruptionNotice(c *C, failureRate float64) { spotInterruptionCheckInterval = time.Second / 8 ec2MetadataBaseURL = stub.URL + checkedLogs := false + checkLogs := func() { + checkedLogs = true + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Checking for spot interruptions every 125ms using instance metadata at http://.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Error checking spot interruptions: 503 Service Unavailable.*`) + if failureRate == 1 { + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Giving up on checking spot interruptions after too many consecutive failures.*`) + return + } + text := `Cloud provider scheduled instance stop at ` + stoptime.Load().(time.Time).Format(time.RFC3339) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*`+text+`.*`) + c.Check(s.api.CalledWith("container.runtime_status.warning", "preemption notice"), NotNil) + c.Check(s.api.CalledWith("container.runtime_status.warningDetail", text), NotNil) + c.Check(s.api.CalledWith("container.runtime_status.preemptionNotice", text), NotNil) + + // Check that the log collection was saved, and the + // container record updated with the new PDH, + // immediately after the preemption notice was + // received -- i.e., while the container is still + // running. + lastpdh := "" + saved := make(map[string]string) // pdh => manifest_text + for _, call := range s.api.Content { + if ctr, ok := call["container"].(arvadosclient.Dict); ok { + if pdh, ok := ctr["log"].(string); ok { + lastpdh = pdh + } + } + if coll, ok := call["collection"].(arvadosclient.Dict); ok { + mt, _ := coll["manifest_text"].(string) + if strings.Contains(mt, ":crunch-run.txt") { + saved[arvados.PortableDataHash(mt)] = mt + } + } + } + logfs, err := (&arvados.Collection{ManifestText: saved[lastpdh]}).FileSystem(s.runner.dispatcherClient, s.runner.DispatcherKeepClient) + c.Assert(err, IsNil) + log, err := fs.ReadFile(arvados.FS(logfs), "crunch-run.txt") + c.Check(err, IsNil) + c.Check(string(log), Matches, `(?ms).*\Q`+text+`\E.*`) + } + go s.runner.checkSpotInterruptionNotices() s.fullRunHelper(c, `{ "command": ["sleep", "3"], @@ -921,19 +934,10 @@ func (s *TestSuite) testSpotInterruptionNotice(c *C, failureRate float64) { stoptime.Store(time.Now().Add(time.Minute).UTC()) token = "different-fake-ec2-metadata-token" time.Sleep(time.Second) + checkLogs() return 0 }) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Checking for spot interruptions every 125ms using instance metadata at http://.*`) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Error checking spot interruptions: 503 Service Unavailable.*`) - if failureRate == 1 { - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Giving up on checking spot interruptions after too many consecutive failures.*`) - } else { - text := `Cloud provider scheduled instance stop at ` + stoptime.Load().(time.Time).Format(time.RFC3339) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*`+text+`.*`) - c.Check(s.api.CalledWith("container.runtime_status.warning", "preemption notice"), NotNil) - c.Check(s.api.CalledWith("container.runtime_status.warningDetail", text), NotNil) - c.Check(s.api.CalledWith("container.runtime_status.preemptionNotice", text), NotNil) - } + c.Check(checkedLogs, Equals, true) } func (s *TestSuite) TestRunTimeExceeded(c *C) { @@ -954,7 +958,7 @@ func (s *TestSuite) TestRunTimeExceeded(c *C) { }) c.Check(s.api.CalledWith("container.state", "Cancelled"), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*maximum run time exceeded.*") + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, "(?ms).*maximum run time exceeded.*") } func (s *TestSuite) TestContainerWaitFails(c *C) { @@ -972,7 +976,7 @@ func (s *TestSuite) TestContainerWaitFails(c *C) { }) c.Check(s.api.CalledWith("container.state", "Cancelled"), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*Container is not running.*") + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, "(?ms).*Container is not running.*") } func (s *TestSuite) TestCrunchstat(c *C) { @@ -995,17 +999,15 @@ func (s *TestSuite) TestCrunchstat(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Assert(s.api.Logs["crunchstat"], NotNil) - c.Check(s.api.Logs["crunchstat"].String(), Matches, `(?ms).*mem \d+ swap \d+ pgmajfault \d+ rss.*`) + c.Check(logFileContent(c, s.runner, "crunchstat.txt"), Matches, `(?ms).*mem \d+ swap \d+ pgmajfault \d+ rss.*`) // Check that we called (*crunchstat.Reporter)Stop(). - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Maximum crunch-run memory rss usage was \d+ bytes\n.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Maximum crunch-run memory rss usage was \d+ bytes\n.*`) } func (s *TestSuite) TestNodeInfoLog(c *C) { - os.Setenv("SLURMD_NODENAME", "compute2") s.fullRunHelper(c, `{ - "command": ["sleep", "1"], + "command": ["true"], "container_image": "`+arvadostest.DockerImage112PDH+`", "cwd": ".", "environment": {}, @@ -1015,26 +1017,22 @@ func (s *TestSuite) TestNodeInfoLog(c *C) { "runtime_constraints": {}, "state": "Locked" }`, nil, func() int { - time.Sleep(time.Second) return 0 }) c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Assert(s.api.Logs["node"], NotNil) - json := s.api.Logs["node"].String() - c.Check(json, Matches, `(?ms).*"uuid": *"zzzzz-7ekkf-2z3mc76g2q73aio".*`) - c.Check(json, Matches, `(?ms).*"total_cpu_cores": *16.*`) - c.Check(json, Not(Matches), `(?ms).*"info":.*`) + json := logFileContent(c, s.runner, "node.json") + c.Check(json, Matches, `(?ms).*"ProviderType": *"a1\.2xlarge".*`) + c.Check(json, Matches, `(?ms).*"Price": *1\.2.*`) - c.Assert(s.api.Logs["node-info"], NotNil) - json = s.api.Logs["node-info"].String() - c.Check(json, Matches, `(?ms).*Host Information.*`) - c.Check(json, Matches, `(?ms).*CPU Information.*`) - c.Check(json, Matches, `(?ms).*Memory Information.*`) - c.Check(json, Matches, `(?ms).*Disk Space.*`) - c.Check(json, Matches, `(?ms).*Disk INodes.*`) + nodeinfo := logFileContent(c, s.runner, "node-info.txt") + c.Check(nodeinfo, Matches, `(?ms).*Host Information.*`) + c.Check(nodeinfo, Matches, `(?ms).*CPU Information.*`) + c.Check(nodeinfo, Matches, `(?ms).*Memory Information.*`) + c.Check(nodeinfo, Matches, `(?ms).*Disk Space.*`) + c.Check(nodeinfo, Matches, `(?ms).*Disk INodes.*`) } func (s *TestSuite) TestLogVersionAndRuntime(c *C) { @@ -1052,11 +1050,10 @@ func (s *TestSuite) TestLogVersionAndRuntime(c *C) { return 0 }) - c.Assert(s.api.Logs["crunch-run"], NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*crunch-run \S+ \(go\S+\) start.*`) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*crunch-run process has uid=\d+\(.+\) gid=\d+\(.+\) groups=\d+\(.+\)(,\d+\(.+\))*\n.*`) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Executing container: zzzzz-zzzzz-zzzzzzzzzzzzzzz.*`) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Using container runtime: stub.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*crunch-run \S+ \(go\S+\) start.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*crunch-run process has uid=\d+\(.+\) gid=\d+\(.+\) groups=\d+\(.+\)(,\d+\(.+\))*\n.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Executing container: zzzzz-zzzzz-zzzzzzzzzzzzzzz.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Using container runtime: stub.*`) } func (s *TestSuite) testLogRSSThresholds(c *C, ram int64, expected []int, notExpected int) { @@ -1072,8 +1069,9 @@ func (s *TestSuite) testLogRSSThresholds(c *C, ram int64, expected []int, notExp "runtime_constraints": {"ram": `+fmt.Sprintf("%d", ram)+`}, "state": "Locked" }`, nil, func() int { return 0 }) - c.Logf("=== crunchstat logs\n%s\n", s.api.Logs["crunchstat"].String()) - logs := s.api.Logs["crunch-run"].String() + logs := logFileContent(c, s.runner, "crunch-run.txt") + c.Log("=== crunchstat logs") + c.Log(logs) pattern := logLineStart + `Container using over %d%% of memory \(rss %d/%d bytes\)` var threshold int for _, threshold = range expected { @@ -1111,7 +1109,7 @@ func (s *TestSuite) TestLogMaximaAfterRun(c *C) { "runtime_constraints": {"ram": `+fmt.Sprintf("%d", s.debian12MemoryCurrent*10)+`}, "state": "Locked" }`, nil, func() int { return 0 }) - logs := s.api.Logs["crunch-run"].String() + logs := logFileContent(c, s.runner, "crunch-run.txt") for _, expected := range []string{ `Maximum disk usage was \d+%, \d+/\d+ bytes`, fmt.Sprintf(`Maximum container memory swap usage was %d bytes`, s.debian12SwapCurrent), @@ -1179,8 +1177,7 @@ func (s *TestSuite) TestContainerRecordLog(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Assert(s.api.Logs["container"], NotNil) - c.Check(s.api.Logs["container"].String(), Matches, `(?ms).*container_image.*`) + c.Check(logFileContent(c, s.runner, "container.json"), Matches, `(?ms).*container_image.*`) } func (s *TestSuite) TestFullRunStderr(c *C) { @@ -1205,8 +1202,8 @@ func (s *TestSuite) TestFullRunStderr(c *C) { c.Check(final["container"].(arvadosclient.Dict)["exit_code"], Equals, 1) c.Check(final["container"].(arvadosclient.Dict)["log"], NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, ".*hello\n") - c.Check(s.api.Logs["stderr"].String(), Matches, ".*world\n") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, ".*hello\n") + c.Check(logFileContent(c, s.runner, "stderr.txt"), Matches, ".*world\n") } func (s *TestSuite) TestFullRunDefaultCwd(c *C) { @@ -1227,8 +1224,7 @@ func (s *TestSuite) TestFullRunDefaultCwd(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Log(s.api.Logs["stdout"]) - c.Check(s.api.Logs["stdout"].String(), Matches, `.*workdir=""\n`) + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, `.*workdir=""`) } func (s *TestSuite) TestFullRunSetCwd(c *C) { @@ -1249,7 +1245,7 @@ func (s *TestSuite) TestFullRunSetCwd(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, ".*/bin\n") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, ".*/bin\n") } func (s *TestSuite) TestFullRunSetOutputStorageClasses(c *C) { @@ -1271,7 +1267,7 @@ func (s *TestSuite) TestFullRunSetOutputStorageClasses(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, ".*/bin\n") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, ".*/bin\n") c.Check(s.testDispatcherKeepClient.StorageClasses, DeepEquals, []string{"foo", "bar"}) c.Check(s.testContainerKeepClient.StorageClasses, DeepEquals, []string{"foo", "bar"}) } @@ -1368,14 +1364,11 @@ func (s *TestSuite) testStopContainer(c *C) { case err = <-done: c.Check(err, IsNil) } - for k, v := range s.api.Logs { - c.Log(k) - c.Log(v.String(), "\n") - } + dumpAllLogFiles(c, s.runner) c.Check(s.api.CalledWith("container.log", nil), NotNil) c.Check(s.api.CalledWith("container.state", "Cancelled"), NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, "(?ms).*foo\n$") + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, "(?ms).*foo\n$") } func (s *TestSuite) TestFullRunSetEnv(c *C) { @@ -1396,7 +1389,7 @@ func (s *TestSuite) TestFullRunSetEnv(c *C) { c.Check(s.api.CalledWith("container.exit_code", 0), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["stdout"].String(), Matches, `.*map\[FROBIZ:bilbo\]\n`) + c.Check(logFileContent(c, s.runner, "stdout.txt"), Matches, `.*map\[FROBIZ:bilbo\]`) } type ArvMountCmdLine struct { @@ -1740,54 +1733,6 @@ func (s *TestSuite) TestSetupMounts(c *C) { cr.CleanupDirs() checkEmpty() } - - // git_tree mounts - { - i = 0 - cr.ArvMountPoint = "" - git_client.InstallProtocol("https", git_http.NewClient(arvados.InsecureHTTPClient)) - cr.token = arvadostest.ActiveToken - cr.Container.Mounts = make(map[string]arvados.Mount) - cr.Container.Mounts = map[string]arvados.Mount{ - "/tip": { - Kind: "git_tree", - UUID: arvadostest.Repository2UUID, - Commit: "fd3531f42995344f36c30b79f55f27b502f3d344", - Path: "/", - }, - "/non-tip": { - Kind: "git_tree", - UUID: arvadostest.Repository2UUID, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - Path: "/", - }, - } - cr.Container.OutputPath = "/tmp" - - bindmounts, err := cr.SetupMounts() - c.Check(err, IsNil) - - for path, mount := range bindmounts { - c.Check(mount.ReadOnly, Equals, !cr.Container.Mounts[path].Writable, Commentf("%s %#v", path, mount)) - } - - data, err := ioutil.ReadFile(bindmounts["/tip"].HostPath + "/dir1/dir2/file with mode 0644") - c.Check(err, IsNil) - c.Check(string(data), Equals, "\000\001\002\003") - _, err = ioutil.ReadFile(bindmounts["/tip"].HostPath + "/file only on testbranch") - c.Check(err, FitsTypeOf, &os.PathError{}) - c.Check(os.IsNotExist(err), Equals, true) - - data, err = ioutil.ReadFile(bindmounts["/non-tip"].HostPath + "/dir1/dir2/file with mode 0644") - c.Check(err, IsNil) - c.Check(string(data), Equals, "\000\001\002\003") - data, err = ioutil.ReadFile(bindmounts["/non-tip"].HostPath + "/file only on testbranch") - c.Check(err, IsNil) - c.Check(string(data), Equals, "testfile\n") - - cr.CleanupDirs() - checkEmpty() - } } func (s *TestSuite) TestStdout(c *C) { @@ -1869,7 +1814,7 @@ func (s *TestSuite) TestFullRunWithAPI(c *C) { }) c.Check(s.api.CalledWith("container.exit_code", 3), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*status code 3\n.*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*status code 3\n.*`) } func (s *TestSuite) TestFullRunSetOutput(c *C) { @@ -1924,7 +1869,7 @@ func (s *TestSuite) TestArvMountRuntimeStatusWarning(c *C) { c.Check(s.api.CalledWith("container.runtime_status.warning", "arv-mount: Keep write error"), NotNil) c.Check(s.api.CalledWith("container.runtime_status.warningDetail", "Test: Keep write error: I am a teapot"), NotNil) c.Check(s.api.CalledWith("container.state", "Complete"), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, `(?ms).*Container exited with status code 137 \(signal 9, SIGKILL\).*`) + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, `(?ms).*Container exited with status code 137 \(signal 9, SIGKILL\).*`) } func (s *TestSuite) TestStdoutWithExcludeFromOutputMountPointUnderOutputDir(c *C) { @@ -2234,13 +2179,14 @@ func (s *TestSuite) TestFullBrokenDocker(c *C) { "state": "Locked" }`, nil, func() int { return 0 }) c.Check(s.api.CalledWith("container.state", nextState), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*unable to run containers.*") + logs := logFileContent(c, s.runner, "crunch-run.txt") + c.Check(logs, Matches, "(?ms).*unable to run containers.*") if s.runner.brokenNodeHook != "" { - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*Running broken node hook.*") - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*killme.*") - c.Check(s.api.Logs["crunch-run"].String(), Not(Matches), "(?ms).*Writing /var/lock/crunch-run-broken to mark node as broken.*") + c.Check(logs, Matches, "(?ms).*Running broken node hook.*") + c.Check(logs, Matches, "(?ms).*killme.*") + c.Check(logs, Not(Matches), "(?ms).*Writing /var/lock/crunch-run-broken to mark node as broken.*") } else { - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*Writing /var/lock/crunch-run-broken to mark node as broken.*") + c.Check(logs, Matches, "(?ms).*Writing /var/lock/crunch-run-broken to mark node as broken.*") } } } @@ -2265,7 +2211,7 @@ func (s *TestSuite) TestBadCommand(c *C) { "state": "Locked" }`, nil, func() int { return 0 }) c.Check(s.api.CalledWith("container.state", "Cancelled"), NotNil) - c.Check(s.api.Logs["crunch-run"].String(), Matches, "(?ms).*Possible causes:.*is missing.*") + c.Check(logFileContent(c, s.runner, "crunch-run.txt"), Matches, "(?ms).*Possible causes:.*is missing.*") } } @@ -2375,7 +2321,7 @@ func (s *TestSuite) TestCalculateCost(c *C) { cr := s.runner cr.costStartTime = now.Add(-time.Hour) var logbuf bytes.Buffer - cr.CrunchLog.Immediate = log.New(&logbuf, "", 0) + cr.CrunchLog = newLogWriter(&logbuf) // if there's no InstanceType env var, cost is calculated as 0 os.Unsetenv("InstanceType") @@ -2386,7 +2332,6 @@ func (s *TestSuite) TestCalculateCost(c *C) { // hasn't found any data), cost is calculated based on // InstanceType env var os.Setenv("InstanceType", `{"Price":1.2}`) - defer os.Unsetenv("InstanceType") cost = cr.calculateCost(now) c.Check(cost, Equals, 1.2) @@ -2432,7 +2377,6 @@ func (s *TestSuite) TestSIGUSR2CostUpdate(c *C) { c.Assert(err, IsNil) os.Setenv("InstanceType", `{"Price":2.2}`) - defer os.Unsetenv("InstanceType") defer func(s string) { lockdir = s }(lockdir) lockdir = c.MkDir() @@ -2503,3 +2447,20 @@ type FakeProcess struct { func (fp FakeProcess) CmdlineSlice() ([]string, error) { return fp.cmdLine, nil } + +func logFileContent(c *C, cr *ContainerRunner, fnm string) string { + buf, err := fs.ReadFile(arvados.FS(cr.LogCollection), fnm) + c.Assert(err, IsNil) + return string(buf) +} + +func dumpAllLogFiles(c *C, cr *ContainerRunner) { + d, err := cr.LogCollection.OpenFile("/", os.O_RDONLY, 0) + c.Assert(err, IsNil) + fis, err := d.Readdir(-1) + c.Assert(err, IsNil) + for _, fi := range fis { + c.Logf("=== %s", fi.Name()) + c.Log(logFileContent(c, cr, fi.Name())) + } +} diff --git a/lib/crunchrun/cuda.go b/lib/crunchrun/cuda.go index c693dbcb96..f91a5c62cd 100644 --- a/lib/crunchrun/cuda.go +++ b/lib/crunchrun/cuda.go @@ -5,13 +5,15 @@ package crunchrun import ( + "fmt" + "io" "os/exec" ) // nvidiaModprobe makes sure all the nvidia kernel modules and devices // are set up. If we don't have all the modules/devices set up we get // "CUDA_ERROR_UNKNOWN". -func nvidiaModprobe(writer *ThrottledLogger) { +func nvidiaModprobe(writer io.Writer) { // The underlying problem is that when normally running // directly on the host, the CUDA SDK will automatically // detect and set up the devices on demand. However, when @@ -42,7 +44,7 @@ func nvidiaModprobe(writer *ThrottledLogger) { nvidiaSmi.Stderr = writer err := nvidiaSmi.Run() if err != nil { - writer.Printf("Warning %v: %v", nvidiaSmi.Args, err) + fmt.Fprintf(writer, "Warning %v: %v\n", nvidiaSmi.Args, err) } // Load the kernel modules & devices associated with @@ -63,7 +65,7 @@ func nvidiaModprobe(writer *ThrottledLogger) { nvmodprobe.Stderr = writer err = nvmodprobe.Run() if err != nil { - writer.Printf("Warning %v: %v", nvmodprobe.Args, err) + fmt.Fprintf(writer, "Warning %v: %v\n", nvmodprobe.Args, err) } } } diff --git a/lib/crunchrun/git_mount.go b/lib/crunchrun/git_mount.go deleted file mode 100644 index 561ea18de4..0000000000 --- a/lib/crunchrun/git_mount.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package crunchrun - -import ( - "fmt" - "net/url" - "os" - "path/filepath" - "regexp" - - "git.arvados.org/arvados.git/sdk/go/arvados" - "gopkg.in/src-d/go-billy.v4/osfs" - git "gopkg.in/src-d/go-git.v4" - git_config "gopkg.in/src-d/go-git.v4/config" - git_plumbing "gopkg.in/src-d/go-git.v4/plumbing" - git_http "gopkg.in/src-d/go-git.v4/plumbing/transport/http" - "gopkg.in/src-d/go-git.v4/storage/memory" -) - -type gitMount arvados.Mount - -var ( - sha1re = regexp.MustCompile(`^[0-9a-f]{40}$`) - repoUUIDre = regexp.MustCompile(`^[0-9a-z]{5}-s0uqq-[0-9a-z]{15}$`) -) - -func (gm gitMount) validate() error { - if gm.Path != "" && gm.Path != "/" { - return fmt.Errorf("cannot mount git_tree with path %q -- only \"/\" is supported", gm.Path) - } - if !sha1re.MatchString(gm.Commit) { - return fmt.Errorf("cannot mount git_tree with commit %q -- must be a 40-char SHA1", gm.Commit) - } - if gm.RepositoryName != "" || gm.GitURL != "" { - return fmt.Errorf("cannot mount git_tree -- repository_name and git_url must be empty") - } - if !repoUUIDre.MatchString(gm.UUID) { - return fmt.Errorf("cannot mount git_tree with uuid %q -- must be a repository UUID", gm.UUID) - } - if gm.Writable { - return fmt.Errorf("writable git_tree mount is not supported") - } - return nil -} - -// ExtractTree extracts the specified tree into dir, which is an -// existing empty local directory. -func (gm gitMount) extractTree(ac *arvados.Client, dir string, token string) error { - err := gm.validate() - if err != nil { - return err - } - dd, err := ac.DiscoveryDocument() - if err != nil { - return fmt.Errorf("error getting discovery document: %w", err) - } - u, err := url.Parse(dd.GitURL) - if err != nil { - return fmt.Errorf("parse gitUrl %q: %s", dd.GitURL, err) - } - u, err = u.Parse("/" + gm.UUID + ".git") - if err != nil { - return fmt.Errorf("build git url from %q, %q: %s", dd.GitURL, gm.UUID, err) - } - store := memory.NewStorage() - repo, err := git.Init(store, osfs.New(dir)) - if err != nil { - return fmt.Errorf("init repo: %s", err) - } - _, err = repo.CreateRemote(&git_config.RemoteConfig{ - Name: "origin", - URLs: []string{u.String()}, - }) - if err != nil { - return fmt.Errorf("create remote %q: %s", u.String(), err) - } - err = repo.Fetch(&git.FetchOptions{ - RemoteName: "origin", - Auth: &git_http.BasicAuth{ - Username: "none", - Password: token, - }, - }) - if err != nil { - return fmt.Errorf("git fetch %q: %s", u.String(), err) - } - wt, err := repo.Worktree() - if err != nil { - return fmt.Errorf("worktree failed: %s", err) - } - err = wt.Checkout(&git.CheckoutOptions{ - Hash: git_plumbing.NewHash(gm.Commit), - }) - if err != nil { - return fmt.Errorf("checkout failed: %s", err) - } - err = filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - // copy user rx bits to group and other, in case - // prevailing umask is more restrictive than 022 - mode := info.Mode() - mode = mode | ((mode >> 3) & 050) | ((mode >> 6) & 5) - return os.Chmod(path, mode) - }) - if err != nil { - return fmt.Errorf("chmod -R %q: %s", dir, err) - } - return nil -} diff --git a/lib/crunchrun/git_mount_test.go b/lib/crunchrun/git_mount_test.go deleted file mode 100644 index ac98dcc480..0000000000 --- a/lib/crunchrun/git_mount_test.go +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package crunchrun - -import ( - "io/ioutil" - "os" - "path/filepath" - - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadostest" - check "gopkg.in/check.v1" - git_client "gopkg.in/src-d/go-git.v4/plumbing/transport/client" - git_http "gopkg.in/src-d/go-git.v4/plumbing/transport/http" -) - -type GitMountSuite struct { - tmpdir string -} - -var _ = check.Suite(&GitMountSuite{}) - -func (s *GitMountSuite) SetUpTest(c *check.C) { - var err error - s.tmpdir, err = ioutil.TempDir("", "") - c.Assert(err, check.IsNil) - git_client.InstallProtocol("https", git_http.NewClient(arvados.InsecureHTTPClient)) -} - -func (s *GitMountSuite) TearDownTest(c *check.C) { - err := os.RemoveAll(s.tmpdir) - c.Check(err, check.IsNil) -} - -// Commit fd3531f is crunch-run-tree-test -func (s *GitMountSuite) TestExtractTree(c *check.C) { - gm := gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - Commit: "fd3531f42995344f36c30b79f55f27b502f3d344", - } - ac := arvados.NewClientFromEnv() - err := gm.extractTree(ac, s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.IsNil) - - fnm := filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0644") - data, err := ioutil.ReadFile(fnm) - c.Check(err, check.IsNil) - c.Check(data, check.DeepEquals, []byte{0, 1, 2, 3}) - fi, err := os.Stat(fnm) - c.Check(err, check.IsNil) - if err == nil { - c.Check(fi.Mode(), check.Equals, os.FileMode(0644)) - } - - fnm = filepath.Join(s.tmpdir, "dir1/dir2/file with mode 0755") - data, err = ioutil.ReadFile(fnm) - c.Check(err, check.IsNil) - c.Check(string(data), check.DeepEquals, "#!/bin/sh\nexec echo OK\n") - fi, err = os.Stat(fnm) - c.Check(err, check.IsNil) - if err == nil { - c.Check(fi.Mode(), check.Equals, os.FileMode(0755)) - } - - // Ensure there's no extra stuff like a ".git" dir - s.checkTmpdirContents(c, []string{"dir1"}) - - // Ensure tmpdir is world-readable and world-executable so the - // UID inside the container can use it. - fi, err = os.Stat(s.tmpdir) - c.Check(err, check.IsNil) - c.Check(fi.Mode()&os.ModePerm, check.Equals, os.FileMode(0755)) -} - -// Commit 5ebfab0 is not the tip of any branch or tag, but is -// reachable in branch "crunch-run-non-tip-test". -func (s *GitMountSuite) TestExtractNonTipCommit(c *check.C) { - gm := gitMount{ - UUID: arvadostest.Repository2UUID, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - } - err := gm.extractTree(arvados.NewClientFromEnv(), s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.IsNil) - - fnm := filepath.Join(s.tmpdir, "file only on testbranch") - data, err := ioutil.ReadFile(fnm) - c.Check(err, check.IsNil) - c.Check(string(data), check.DeepEquals, "testfile\n") -} - -func (s *GitMountSuite) TestNonexistentRepository(c *check.C) { - gm := gitMount{ - Path: "/", - UUID: "zzzzz-s0uqq-nonexistentrepo", - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - } - err := gm.extractTree(arvados.NewClientFromEnv(), s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.NotNil) - c.Check(err, check.ErrorMatches, ".*repository not found.*") - - s.checkTmpdirContents(c, []string{}) -} - -func (s *GitMountSuite) TestNonexistentCommit(c *check.C) { - gm := gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - Commit: "bb66b6bb6b6bbb6b6b6b66b6b6b6b6b6b6b6b66b", - } - err := gm.extractTree(arvados.NewClientFromEnv(), s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.NotNil) - c.Check(err, check.ErrorMatches, ".*object not found.*") - - s.checkTmpdirContents(c, []string{}) -} - -func (s *GitMountSuite) TestGitUrlDiscoveryFails(c *check.C) { - delete(discoveryMap, "gitUrl") - gm := gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - } - err := gm.extractTree(&arvados.Client{}, s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.ErrorMatches, ".*error getting discovery doc.*") -} - -func (s *GitMountSuite) TestInvalid(c *check.C) { - for _, trial := range []struct { - gm gitMount - matcher string - }{ - { - gm: gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - Commit: "abc123", - }, - matcher: ".*SHA1.*", - }, - { - gm: gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - RepositoryName: arvadostest.Repository2Name, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - }, - matcher: ".*repository_name.*", - }, - { - gm: gitMount{ - Path: "/", - GitURL: "https://localhost:0/" + arvadostest.Repository2Name + ".git", - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - }, - matcher: ".*git_url.*", - }, - { - gm: gitMount{ - Path: "/dir1/", - UUID: arvadostest.Repository2UUID, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - }, - matcher: ".*path.*", - }, - { - gm: gitMount{ - Path: "/", - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - }, - matcher: ".*UUID.*", - }, - { - gm: gitMount{ - Path: "/", - UUID: arvadostest.Repository2UUID, - Commit: "5ebfab0522851df01fec11ec55a6d0f4877b542e", - Writable: true, - }, - matcher: ".*writable.*", - }, - } { - err := trial.gm.extractTree(arvados.NewClientFromEnv(), s.tmpdir, arvadostest.ActiveToken) - c.Check(err, check.NotNil) - s.checkTmpdirContents(c, []string{}) - - err = trial.gm.validate() - c.Check(err, check.ErrorMatches, trial.matcher) - } -} - -func (s *GitMountSuite) checkTmpdirContents(c *check.C, expect []string) { - f, err := os.Open(s.tmpdir) - c.Check(err, check.IsNil) - names, err := f.Readdirnames(-1) - c.Check(err, check.IsNil) - c.Check(names, check.DeepEquals, expect) -} diff --git a/lib/crunchrun/integration_test.go b/lib/crunchrun/integration_test.go index ef5cc567db..38c589f698 100644 --- a/lib/crunchrun/integration_test.go +++ b/lib/crunchrun/integration_test.go @@ -148,6 +148,7 @@ func (s *integrationSuite) setup(c *C) { "state": s.cr.State, "command": s.cr.Command, "output_path": s.cr.OutputPath, + "output_glob": s.cr.OutputGlob, "container_image": s.cr.ContainerImage, "mounts": s.cr.Mounts, "runtime_constraints": s.cr.RuntimeConstraints, @@ -274,6 +275,19 @@ func (s *integrationSuite) TestRunTrivialContainerWithNoLocalKeepstore(c *C) { c.Check(s.logFiles["crunch-run.txt"], Matches, `(?ms).*loaded config file \Q`+os.Getenv("ARVADOS_CONFIG")+`\E\n.*`) } +func (s *integrationSuite) TestRunTrivialContainerWithOutputGlob(c *C) { + s.cr.OutputGlob = []string{"js?n"} + s.testRunTrivialContainer(c) + fs, err := s.outputCollection.FileSystem(s.client, s.kc) + c.Assert(err, IsNil) + _, err = fs.Stat("json") + c.Check(err, IsNil) + _, err = fs.Stat("inputfile") + c.Check(err, Equals, os.ErrNotExist) + _, err = fs.Stat("emptydir") + c.Check(err, Equals, os.ErrNotExist) +} + func (s *integrationSuite) testRunTrivialContainer(c *C) { if err := exec.Command("which", s.engine).Run(); err != nil { c.Skip(fmt.Sprintf("%s: %s", s.engine, err)) @@ -323,34 +337,37 @@ func (s *integrationSuite) testRunTrivialContainer(c *C) { var output arvados.Collection err = s.client.RequestAndDecode(&output, "GET", "arvados/v1/collections/"+s.cr.OutputUUID, nil, nil) c.Assert(err, IsNil) - fs, err = output.FileSystem(s.client, s.kc) - c.Assert(err, IsNil) - if f, err := fs.Open("inputfile"); c.Check(err, IsNil) { - defer f.Close() - buf, err := ioutil.ReadAll(f) - c.Check(err, IsNil) - c.Check(string(buf), Equals, "inputdata") - } - if f, err := fs.Open("json"); c.Check(err, IsNil) { - defer f.Close() - buf, err := ioutil.ReadAll(f) - c.Check(err, IsNil) - c.Check(string(buf), Equals, `["foo",{"foo":"bar"},null]`) - } - if fi, err := fs.Stat("emptydir"); c.Check(err, IsNil) { - c.Check(fi.IsDir(), Equals, true) - } - if d, err := fs.Open("emptydir"); c.Check(err, IsNil) { - defer d.Close() - fis, err := d.Readdir(-1) + s.outputCollection = output + + if len(s.cr.OutputGlob) == 0 { + fs, err = output.FileSystem(s.client, s.kc) c.Assert(err, IsNil) - // crunch-run still saves a ".keep" file to preserve - // empty dirs even though that shouldn't be - // necessary. Ideally we would do: - // c.Check(fis, HasLen, 0) - for _, fi := range fis { - c.Check(fi.Name(), Equals, ".keep") + if f, err := fs.Open("inputfile"); c.Check(err, IsNil) { + defer f.Close() + buf, err := ioutil.ReadAll(f) + c.Check(err, IsNil) + c.Check(string(buf), Equals, "inputdata") + } + if f, err := fs.Open("json"); c.Check(err, IsNil) { + defer f.Close() + buf, err := ioutil.ReadAll(f) + c.Check(err, IsNil) + c.Check(string(buf), Equals, `["foo",{"foo":"bar"},null]`) + } + if fi, err := fs.Stat("emptydir"); c.Check(err, IsNil) { + c.Check(fi.IsDir(), Equals, true) + } + if d, err := fs.Open("emptydir"); c.Check(err, IsNil) { + defer d.Close() + fis, err := d.Readdir(-1) + c.Assert(err, IsNil) + // crunch-run still saves a ".keep" file to preserve + // empty dirs even though that shouldn't be + // necessary. Ideally we would do: + // c.Check(fis, HasLen, 0) + for _, fi := range fis { + c.Check(fi.Name(), Equals, ".keep") + } } } - s.outputCollection = output } diff --git a/lib/crunchrun/logging.go b/lib/crunchrun/logging.go index 91a1b77cf4..04c3724969 100644 --- a/lib/crunchrun/logging.go +++ b/lib/crunchrun/logging.go @@ -5,373 +5,82 @@ package crunchrun import ( - "bufio" "bytes" "encoding/json" - "fmt" "io" "log" - "regexp" - "strings" - "sync" "time" - - "git.arvados.org/arvados.git/sdk/go/arvadosclient" ) -// Timestamper is the signature for a function that takes a timestamp and -// return a formated string value. -type Timestamper func(t time.Time) string - -// Logging plumbing: -// -// ThrottledLogger.Logger -> ThrottledLogger.Write -> -// ThrottledLogger.buf -> ThrottledLogger.flusher -> -// ArvLogWriter.Write -> CollectionFileWriter.Write | Api.Create -// -// For stdout/stderr ReadWriteLines additionally runs as a goroutine to pull -// data from the stdout/stderr Reader and send to the Logger. +// rfc3339NanoFixed is a fixed-width version of time.RFC3339Nano. +const rfc3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" -// ThrottledLogger accepts writes, prepends a timestamp to each line of the -// write, and periodically flushes to a downstream writer. It supports the -// "Logger" and "WriteCloser" interfaces. -type ThrottledLogger struct { - *log.Logger - buf *bytes.Buffer - sync.Mutex - writer io.WriteCloser - flush chan struct{} - stopped chan struct{} - stopping chan struct{} - Timestamper - Immediate *log.Logger - pendingFlush bool +// prefixer wraps an io.Writer, inserting a string returned by +// prefixFunc at the beginning of each line. +type prefixer struct { + writer io.Writer + prefixFunc func() string + unfinished bool // true if the most recent write ended with a non-newline char } -// RFC3339NanoFixed is a fixed-width version of time.RFC3339Nano. -const RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" - -// RFC3339Timestamp formats t as RFC3339NanoFixed. -func RFC3339Timestamp(t time.Time) string { - return t.Format(RFC3339NanoFixed) -} - -// Write prepends a timestamp to each line of the input data and -// appends to the internal buffer. Each line is also logged to -// tl.Immediate, if tl.Immediate is not nil. -func (tl *ThrottledLogger) Write(p []byte) (n int, err error) { - tl.Mutex.Lock() - defer tl.Mutex.Unlock() - - if tl.buf == nil { - tl.buf = &bytes.Buffer{} - } - - now := tl.Timestamper(time.Now().UTC()) - sc := bufio.NewScanner(bytes.NewBuffer(p)) - for err == nil && sc.Scan() { - out := fmt.Sprintf("%s %s\n", now, sc.Bytes()) - if tl.Immediate != nil { - tl.Immediate.Print(out[:len(out)-1]) - } - _, err = io.WriteString(tl.buf, out) - } - if err == nil { - err = sc.Err() - if err == nil { - n = len(p) - } - } - - if int64(tl.buf.Len()) >= crunchLogBytesPerEvent { - // Non-blocking send. Try send a flush if it is ready to - // accept it. Otherwise do nothing because a flush is already - // pending. - select { - case tl.flush <- struct{}{}: - default: - } +// newTimestamper wraps an io.Writer, inserting an RFC3339NanoFixed +// timestamp at the beginning of each line. +func newTimestamper(w io.Writer) *prefixer { + return &prefixer{ + writer: w, + prefixFunc: func() string { return time.Now().UTC().Format(rfc3339NanoFixed + " ") }, } - - return } -// Periodically check the current buffer; if not empty, send it on the -// channel to the goWriter goroutine. -func (tl *ThrottledLogger) flusher() { - ticker := time.NewTicker(time.Duration(crunchLogSecondsBetweenEvents)) - defer ticker.Stop() - for stopping := false; !stopping; { - select { - case <-tl.stopping: - // flush tl.buf and exit the loop - stopping = true - case <-tl.flush: - case <-ticker.C: - } - - var ready *bytes.Buffer - - tl.Mutex.Lock() - ready, tl.buf = tl.buf, &bytes.Buffer{} - tl.Mutex.Unlock() - - if ready != nil && ready.Len() > 0 { - tl.writer.Write(ready.Bytes()) - } - } - close(tl.stopped) -} - -// Close the flusher goroutine and wait for it to complete, then close the -// underlying Writer. -func (tl *ThrottledLogger) Close() error { - select { - case <-tl.stopping: - // already stopped - default: - close(tl.stopping) +// newStringPrefixer wraps an io.Writer, inserting the given string at +// the beginning of each line. The given string should include a +// trailing space for readability. +func newStringPrefixer(w io.Writer, s string) *prefixer { + return &prefixer{ + writer: w, + prefixFunc: func() string { return s }, } - <-tl.stopped - return tl.writer.Close() } -const ( - // MaxLogLine is the maximum length of stdout/stderr lines before they are split. - MaxLogLine = 1 << 12 -) - -// ReadWriteLines reads lines from a reader and writes to a Writer, with long -// line splitting. -func ReadWriteLines(in io.Reader, writer io.Writer, done chan<- bool) { - reader := bufio.NewReaderSize(in, MaxLogLine) - var prefix string - for { - line, isPrefix, err := reader.ReadLine() - if err == io.EOF { - break - } else if err != nil { - writer.Write([]byte(fmt.Sprintln("error reading container log:", err))) - } - var suffix string - if isPrefix { - suffix = "[...]\n" - } - - if prefix == "" && suffix == "" { - writer.Write(line) - } else { - writer.Write([]byte(fmt.Sprint(prefix, string(line), suffix))) +func (tp *prefixer) Write(p []byte) (n int, err error) { + for len(p) > 0 && err == nil { + if !tp.unfinished { + _, err = io.WriteString(tp.writer, tp.prefixFunc()) + if err != nil { + return + } } - - // Set up prefix for following line - if isPrefix { - prefix = "[...]" + newline := bytes.IndexRune(p, '\n') + var nn int + if newline < 0 { + tp.unfinished = true + nn, err = tp.writer.Write(p) + p = nil } else { - prefix = "" + tp.unfinished = false + nn, err = tp.writer.Write(p[:newline+1]) + p = p[nn:] } + n += nn } - done <- true -} - -// NewThrottledLogger creates a new thottled logger that -// - prepends timestamps to each line, and -// - batches log messages and only calls the underlying Writer -// at most once per "crunchLogSecondsBetweenEvents" seconds. -func NewThrottledLogger(writer io.WriteCloser) *ThrottledLogger { - tl := &ThrottledLogger{} - tl.flush = make(chan struct{}, 1) - tl.stopped = make(chan struct{}) - tl.stopping = make(chan struct{}) - tl.writer = writer - tl.Logger = log.New(tl, "", 0) - tl.Timestamper = RFC3339Timestamp - go tl.flusher() - return tl -} - -// Log throttling rate limiting config parameters -var crunchLimitLogBytesPerJob int64 = 67108864 -var crunchLogThrottleBytes int64 = 65536 -var crunchLogThrottlePeriod time.Duration = time.Second * 60 -var crunchLogThrottleLines int64 = 1024 -var crunchLogPartialLineThrottlePeriod time.Duration = time.Second * 5 -var crunchLogBytesPerEvent int64 = 4096 -var crunchLogSecondsBetweenEvents = time.Second -var crunchLogUpdatePeriod = time.Hour / 2 -var crunchLogUpdateSize = int64(1 << 25) - -// ArvLogWriter is an io.WriteCloser that processes each write by -// writing it through to another io.WriteCloser (typically a -// CollectionFileWriter) and creating an Arvados log entry. -type ArvLogWriter struct { - ArvClient IArvadosClient - UUID string - loggingStream string - writeCloser io.WriteCloser - - // for rate limiting - bytesLogged int64 - logThrottleResetTime time.Time - logThrottleLinesSoFar int64 - logThrottleBytesSoFar int64 - logThrottleBytesSkipped int64 - logThrottleIsOpen bool - logThrottlePartialLineNextAt time.Time - logThrottleFirstPartialLine bool - bufToFlush bytes.Buffer - bufFlushedAt time.Time - closing bool + return } -func (arvlog *ArvLogWriter) Write(p []byte) (int, error) { - // Write to the next writer in the chain (a file in Keep) - var err1 error - if arvlog.writeCloser != nil { - _, err1 = arvlog.writeCloser.Write(p) - } - - // write to API after checking rate limit - now := time.Now() - - if now.After(arvlog.logThrottleResetTime) { - // It has been more than throttle_period seconds since the last - // checkpoint; so reset the throttle - if arvlog.logThrottleBytesSkipped > 0 { - arvlog.bufToFlush.WriteString(fmt.Sprintf("%s Skipped %d bytes of log\n", RFC3339Timestamp(now.UTC()), arvlog.logThrottleBytesSkipped)) - } - - arvlog.logThrottleResetTime = now.Add(crunchLogThrottlePeriod) - arvlog.logThrottleBytesSoFar = 0 - arvlog.logThrottleLinesSoFar = 0 - arvlog.logThrottleBytesSkipped = 0 - arvlog.logThrottleIsOpen = true - } - - lines := bytes.Split(p, []byte("\n")) - - for _, line := range lines { - // Short circuit the counting code if we're just going to throw - // away the data anyway. - if !arvlog.logThrottleIsOpen { - arvlog.logThrottleBytesSkipped += int64(len(line)) - continue - } else if len(line) == 0 { - continue - } - - // check rateLimit - logOpen, msg := arvlog.rateLimit(line, now) - if logOpen { - arvlog.bufToFlush.WriteString(string(msg) + "\n") - } - } - - if (int64(arvlog.bufToFlush.Len()) >= crunchLogBytesPerEvent || - (now.Sub(arvlog.bufFlushedAt) >= crunchLogSecondsBetweenEvents) || - arvlog.closing) && (arvlog.bufToFlush.Len() > 0) { - // write to API - lr := arvadosclient.Dict{"log": arvadosclient.Dict{ - "object_uuid": arvlog.UUID, - "event_type": arvlog.loggingStream, - "properties": map[string]string{"text": arvlog.bufToFlush.String()}}} - err2 := arvlog.ArvClient.Create("logs", lr, nil) - - arvlog.bufToFlush = bytes.Buffer{} - arvlog.bufFlushedAt = now - - if err1 != nil || err2 != nil { - return 0, fmt.Errorf("%s ; %s", err1, err2) - } - } - - return len(p), nil +// logWriter adds log.Logger methods to an io.Writer. +type logWriter struct { + io.Writer + *log.Logger } -// Close the underlying writer -func (arvlog *ArvLogWriter) Close() (err error) { - arvlog.closing = true - arvlog.Write([]byte{}) - if arvlog.writeCloser != nil { - err = arvlog.writeCloser.Close() - arvlog.writeCloser = nil +func newLogWriter(w io.Writer) *logWriter { + return &logWriter{ + Writer: w, + Logger: log.New(w, "", 0), } - return err } -var lineRegexp = regexp.MustCompile(`^\S+ (.*)`) - -// Test for hard cap on total output and for log throttling. Returns whether -// the log line should go to output or not. Returns message if limit exceeded. -func (arvlog *ArvLogWriter) rateLimit(line []byte, now time.Time) (bool, []byte) { - message := "" - lineSize := int64(len(line)) - - if arvlog.logThrottleIsOpen { - matches := lineRegexp.FindStringSubmatch(string(line)) - - if len(matches) == 2 && strings.HasPrefix(matches[1], "[...]") && strings.HasSuffix(matches[1], "[...]") { - // This is a partial line. - - if arvlog.logThrottleFirstPartialLine { - // Partial should be suppressed. First time this is happening for this line so provide a message instead. - arvlog.logThrottleFirstPartialLine = false - arvlog.logThrottlePartialLineNextAt = now.Add(crunchLogPartialLineThrottlePeriod) - arvlog.logThrottleBytesSkipped += lineSize - return true, []byte(fmt.Sprintf("%s Rate-limiting partial segments of long lines to one every %d seconds.", - RFC3339Timestamp(now.UTC()), crunchLogPartialLineThrottlePeriod/time.Second)) - } else if now.After(arvlog.logThrottlePartialLineNextAt) { - // The throttle period has passed. Update timestamp and let it through. - arvlog.logThrottlePartialLineNextAt = now.Add(crunchLogPartialLineThrottlePeriod) - } else { - // Suppress line. - arvlog.logThrottleBytesSkipped += lineSize - return false, line - } - } else { - // Not a partial line so reset. - arvlog.logThrottlePartialLineNextAt = time.Time{} - arvlog.logThrottleFirstPartialLine = true - } - - arvlog.bytesLogged += lineSize - arvlog.logThrottleBytesSoFar += lineSize - arvlog.logThrottleLinesSoFar++ - - if arvlog.bytesLogged > crunchLimitLogBytesPerJob { - message = fmt.Sprintf("%s Exceeded log limit %d bytes (crunch_limit_log_bytes_per_job). Log will be truncated.", - RFC3339Timestamp(now.UTC()), crunchLimitLogBytesPerJob) - arvlog.logThrottleResetTime = now.Add(time.Duration(365 * 24 * time.Hour)) - arvlog.logThrottleIsOpen = false - - } else if arvlog.logThrottleBytesSoFar > crunchLogThrottleBytes { - remainingTime := arvlog.logThrottleResetTime.Sub(now) - message = fmt.Sprintf("%s Exceeded rate %d bytes per %d seconds (crunch_log_throttle_bytes). Logging will be silenced for the next %d seconds.", - RFC3339Timestamp(now.UTC()), crunchLogThrottleBytes, crunchLogThrottlePeriod/time.Second, remainingTime/time.Second) - arvlog.logThrottleIsOpen = false - - } else if arvlog.logThrottleLinesSoFar > crunchLogThrottleLines { - remainingTime := arvlog.logThrottleResetTime.Sub(now) - message = fmt.Sprintf("%s Exceeded rate %d lines per %d seconds (crunch_log_throttle_lines), logging will be silenced for the next %d seconds.", - RFC3339Timestamp(now.UTC()), crunchLogThrottleLines, crunchLogThrottlePeriod/time.Second, remainingTime/time.Second) - arvlog.logThrottleIsOpen = false - - } - } - - if !arvlog.logThrottleIsOpen { - // Don't log anything if any limit has been exceeded. Just count lossage. - arvlog.logThrottleBytesSkipped += lineSize - } - - if message != "" { - // Yes, write to logs, but use our "rate exceeded" message - // instead of the log message that exceeded the limit. - message += " A complete log is still being written to Keep, and will be available when the job finishes." - return true, []byte(message) - } - return arvlog.logThrottleIsOpen, line -} +var crunchLogUpdatePeriod = time.Hour / 2 +var crunchLogUpdateSize = int64(1 << 25) // load the rate limit discovery config parameters func loadLogThrottleParams(clnt IArvadosClient) { @@ -394,13 +103,6 @@ func loadLogThrottleParams(clnt IArvadosClient) { } } - loadInt64(&crunchLimitLogBytesPerJob, "crunchLimitLogBytesPerJob") - loadInt64(&crunchLogThrottleBytes, "crunchLogThrottleBytes") - loadDuration(&crunchLogThrottlePeriod, "crunchLogThrottlePeriod") - loadInt64(&crunchLogThrottleLines, "crunchLogThrottleLines") - loadDuration(&crunchLogPartialLineThrottlePeriod, "crunchLogPartialLineThrottlePeriod") - loadInt64(&crunchLogBytesPerEvent, "crunchLogBytesPerEvent") - loadDuration(&crunchLogSecondsBetweenEvents, "crunchLogSecondsBetweenEvents") loadInt64(&crunchLogUpdateSize, "crunchLogUpdateSize") loadDuration(&crunchLogUpdatePeriod, "crunchLogUpdatePeriod") diff --git a/lib/crunchrun/logging_test.go b/lib/crunchrun/logging_test.go index 42f165fd75..e747a2069e 100644 --- a/lib/crunchrun/logging_test.go +++ b/lib/crunchrun/logging_test.go @@ -13,26 +13,25 @@ import ( "time" "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadosclient" . "gopkg.in/check.v1" check "gopkg.in/check.v1" ) -type LoggingTestSuite struct { - client *arvados.Client -} - -type TestTimestamper struct { - count int +// newTestTimestamper wraps an io.Writer, inserting a predictable +// RFC3339NanoFixed timestamp at the beginning of each line. +func newTestTimestamper(w io.Writer) *prefixer { + count := 0 + return &prefixer{ + writer: w, + prefixFunc: func() string { + count++ + return fmt.Sprintf("2015-12-29T15:51:45.%09dZ ", count) + }, + } } -func (stamper *TestTimestamper) Timestamp(t time.Time) string { - stamper.count++ - t, err := time.ParseInLocation(time.RFC3339Nano, fmt.Sprintf("2015-12-29T15:51:45.%09dZ", stamper.count), t.Location()) - if err != nil { - panic(err) - } - return RFC3339Timestamp(t) +type LoggingTestSuite struct { + client *arvados.Client } // Gocheck boilerplate @@ -48,26 +47,20 @@ func (s *LoggingTestSuite) TestWriteLogs(c *C) { api := &ArvTestClient{} kc := &KeepTestClient{} defer kc.Close() - cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzzzzzzzzzzzz") + cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-dz642-zzzzzzzzzzzzzzz") + c.Assert(err, IsNil) + f, err := cr.openLogFile("crunch-run") c.Assert(err, IsNil) - cr.CrunchLog.Timestamper = (&TestTimestamper{}).Timestamp + cr.CrunchLog = newLogWriter(newTestTimestamper(f)) cr.CrunchLog.Print("Hello world!") cr.CrunchLog.Print("Goodbye") - cr.CrunchLog.Close() - - c.Check(api.Calls, Equals, 1) - - mt, err := cr.LogCollection.MarshalManifest(".") - c.Check(err, IsNil) - c.Check(mt, Equals, ". 74561df9ae65ee9f35d5661d42454264+83 0:83:crunch-run.txt\n") - logtext := "2015-12-29T15:51:45.000000001Z Hello world!\n" + - "2015-12-29T15:51:45.000000002Z Goodbye\n" + c.Check(api.Calls, Equals, 0) - c.Check(api.Content[0]["log"].(arvadosclient.Dict)["event_type"], Equals, "crunch-run") - c.Check(api.Content[0]["log"].(arvadosclient.Dict)["properties"].(map[string]string)["text"], Equals, logtext) - c.Check(string(kc.Content), Equals, logtext) + logs := logFileContent(c, cr, "crunch-run.txt") + c.Check(logs, Matches, `....-..-..T..:..:..\..........Z Hello world!\n`+ + `....-..-..T..:..:..\..........Z Goodbye\n`) } func (s *LoggingTestSuite) TestWriteLogsLarge(c *C) { @@ -79,59 +72,34 @@ func (s *LoggingTestSuite) TestWriteLogsLarge(c *C) { defer kc.Close() cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzzzzzzzzzzzz") c.Assert(err, IsNil) - cr.CrunchLog.Timestamper = (&TestTimestamper{}).Timestamp - cr.CrunchLog.Immediate = nil - + f, err := cr.openLogFile("crunch-run") + c.Assert(err, IsNil) + cr.CrunchLog = newLogWriter(newTestTimestamper(f)) for i := 0; i < 2000000; i++ { cr.CrunchLog.Printf("Hello %d", i) } cr.CrunchLog.Print("Goodbye") - cr.CrunchLog.Close() - - c.Check(api.Calls > 0, Equals, true) - c.Check(api.Calls < 2000000, Equals, true) - - mt, err := cr.LogCollection.MarshalManifest(".") - c.Check(err, IsNil) - c.Check(mt, Equals, ". 9c2c05d1fae6aaa8af85113ba725716d+67108864 80b821383a07266c2a66a4566835e26e+21780065 0:88888929:crunch-run.txt\n") -} - -func (s *LoggingTestSuite) TestWriteMultipleLogs(c *C) { - api := &ArvTestClient{} - kc := &KeepTestClient{} - defer kc.Close() - cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzzzzzzzzzzzz") - c.Assert(err, IsNil) - ts := &TestTimestamper{} - cr.CrunchLog.Timestamper = ts.Timestamp - w, err := cr.NewLogWriter("stdout") - c.Assert(err, IsNil) - stdout := NewThrottledLogger(w) - stdout.Timestamper = ts.Timestamp - - cr.CrunchLog.Print("Hello world!") - stdout.Print("Doing stuff") - cr.CrunchLog.Print("Goodbye") - stdout.Print("Blurb") - cr.CrunchLog.Close() - stdout.Close() - logText := make(map[string]string) - for _, content := range api.Content { - log := content["log"].(arvadosclient.Dict) - logText[log["event_type"].(string)] += log["properties"].(map[string]string)["text"] - } - - c.Check(logText["crunch-run"], Equals, `2015-12-29T15:51:45.000000001Z Hello world! -2015-12-29T15:51:45.000000003Z Goodbye -`) - c.Check(logText["stdout"], Equals, `2015-12-29T15:51:45.000000002Z Doing stuff -2015-12-29T15:51:45.000000004Z Blurb + logs := logFileContent(c, cr, "crunch-run.txt") + c.Check(strings.Count(logs, "\n"), Equals, 2000001) + // Redact most of the logs except the start/end for the regexp + // match -- otherwise, when the regexp fails, gocheck spams + // the test logs with tens of megabytes of quoted strings. + c.Assert(len(logs) > 10000, Equals, true) + c.Check(logs[:500]+"\n...\n"+logs[len(logs)-500:], Matches, `(?ms)2015-12-29T15:51:45.000000001Z Hello 0 +2015-12-29T15:51:45.000000002Z Hello 1 +2015-12-29T15:51:45.000000003Z Hello 2 +2015-12-29T15:51:45.000000004Z Hello 3 +.* +2015-12-29T15:51:45.001999998Z Hello 1999997 +2015-12-29T15:51:45.001999999Z Hello 1999998 +2015-12-29T15:51:45.002000000Z Hello 1999999 +2015-12-29T15:51:45.002000001Z Goodbye `) mt, err := cr.LogCollection.MarshalManifest(".") c.Check(err, IsNil) - c.Check(mt, Equals, ". 48f9023dc683a850b1c9b482b14c4b97+163 0:83:crunch-run.txt 83:80:stdout.txt\n") + c.Check(mt, Equals, ". 9c2c05d1fae6aaa8af85113ba725716d+67108864 80b821383a07266c2a66a4566835e26e+21780065 0:88888929:crunch-run.txt\n") } func (s *LoggingTestSuite) TestLogUpdate(c *C) { @@ -149,14 +117,13 @@ func (s *LoggingTestSuite) TestLogUpdate(c *C) { api := &ArvTestClient{} kc := &KeepTestClient{} defer kc.Close() - cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzzzzzzzzzzzz") + cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-dz642-zzzzzzzzzzzzzzz") c.Assert(err, IsNil) - ts := &TestTimestamper{} - cr.CrunchLog.Timestamper = ts.Timestamp - w, err := cr.NewLogWriter("stdout") + f, err := cr.openLogFile("crunch-run") + c.Assert(err, IsNil) + cr.CrunchLog = newLogWriter(newTestTimestamper(f)) + stdout, err := cr.openLogFile("stdout") c.Assert(err, IsNil) - stdout := NewThrottledLogger(w) - stdout.Timestamper = ts.Timestamp c.Check(cr.logUUID, Equals, "") cr.CrunchLog.Printf("Hello %1000s", "space") @@ -165,68 +132,18 @@ func (s *LoggingTestSuite) TestLogUpdate(c *C) { } c.Check(cr.logUUID, Not(Equals), "") cr.CrunchLog.Print("Goodbye") - fmt.Fprint(stdout, "Goodbye\n") - cr.CrunchLog.Close() - stdout.Close() - w.Close() + fmt.Fprintln(stdout, "Goodbye") + + c.Check(logFileContent(c, cr, "crunch-run.txt"), Matches, `....-..-..T..:..:............Z Hello {995}space\n`+ + `....-..-..T..:..:............Z Goodbye\n`) + c.Check(logFileContent(c, cr, "stdout.txt"), Matches, `Goodbye\n`) mt, err := cr.LogCollection.MarshalManifest(".") c.Check(err, IsNil) - // Block packing depends on whether there's an update - // between the two Goodbyes -- either way the first - // block will be 4dc76. - c.Check(mt, Matches, `. 4dc76e0a212bfa30c39d76d8c16da0c0\+1038 (afc503bc1b9a828b4bb543cb629e936c\+78|90699dc22545cd74a0664303f70bc05a\+39 276b49339fd5203d15a93ff3de11bfb9\+39) 0:1077:crunch-run.txt 1077:39:stdout.txt\n`) + c.Check(mt, Matches, `. 4dc76e0a212bfa30c39d76d8c16da0c0\+1038 5be52044a8c51e7b62dd62be07872968\+47 0:1077:crunch-run.txt 1077:8:stdout.txt\n`) } } -func (s *LoggingTestSuite) TestWriteLogsWithRateLimitThrottleBytes(c *C) { - s.testWriteLogsWithRateLimit(c, "crunchLogThrottleBytes", 50, 65536, "Exceeded rate 50 bytes per 60 seconds") -} - -func (s *LoggingTestSuite) TestWriteLogsWithRateLimitThrottleLines(c *C) { - s.testWriteLogsWithRateLimit(c, "crunchLogThrottleLines", 1, 1024, "Exceeded rate 1 lines per 60 seconds") -} - -func (s *LoggingTestSuite) TestWriteLogsWithRateLimitThrottleBytesPerEvent(c *C) { - s.testWriteLogsWithRateLimit(c, "crunchLimitLogBytesPerJob", 50, 67108864, "Exceeded log limit 50 bytes (crunch_limit_log_bytes_per_job)") -} - -func (s *LoggingTestSuite) TestWriteLogsWithZeroBytesPerJob(c *C) { - s.testWriteLogsWithRateLimit(c, "crunchLimitLogBytesPerJob", 0, 67108864, "Exceeded log limit 0 bytes (crunch_limit_log_bytes_per_job)") -} - -func (s *LoggingTestSuite) testWriteLogsWithRateLimit(c *C, throttleParam string, throttleValue int, throttleDefault int, expected string) { - discoveryMap[throttleParam] = float64(throttleValue) - defer func() { - discoveryMap[throttleParam] = float64(throttleDefault) - }() - - api := &ArvTestClient{} - kc := &KeepTestClient{} - defer kc.Close() - cr, err := NewContainerRunner(s.client, api, kc, "zzzzz-zzzzzzzzzzzzzzz") - c.Assert(err, IsNil) - cr.CrunchLog.Timestamper = (&TestTimestamper{}).Timestamp - - cr.CrunchLog.Print("Hello world!") - cr.CrunchLog.Print("Goodbye") - cr.CrunchLog.Close() - - c.Check(api.Calls, Equals, 1) - - mt, err := cr.LogCollection.MarshalManifest(".") - c.Check(err, IsNil) - c.Check(mt, Equals, ". 74561df9ae65ee9f35d5661d42454264+83 0:83:crunch-run.txt\n") - - logtext := "2015-12-29T15:51:45.000000001Z Hello world!\n" + - "2015-12-29T15:51:45.000000002Z Goodbye\n" - - c.Check(api.Content[0]["log"].(arvadosclient.Dict)["event_type"], Equals, "crunch-run") - stderrLog := api.Content[0]["log"].(arvadosclient.Dict)["properties"].(map[string]string)["text"] - c.Check(true, Equals, strings.Contains(stderrLog, expected)) - c.Check(string(kc.Content), Equals, logtext) -} - type filterSuite struct{} var _ = Suite(&filterSuite{}) diff --git a/lib/install/deps.go b/lib/install/deps.go index 9720a30d26..b27a14a501 100644 --- a/lib/install/deps.go +++ b/lib/install/deps.go @@ -35,7 +35,7 @@ const goversion = "1.20.6" const ( defaultRubyVersion = "3.2.2" - defaultBundlerVersion = "2.2.19" + defaultBundlerVersion = "~> 2.4.0" defaultSingularityVersion = "3.10.4" pjsversion = "1.9.8" geckoversion = "0.24.0" @@ -123,7 +123,7 @@ func (inst *installCommand) RunCommand(prog string, args []string, stdin io.Read fmt.Fprintf(stderr, "invalid argument %q for -ruby-version\n", inst.RubyVersion) return 2 } - if ok, _ := regexp.MatchString(`^\d`, inst.BundlerVersion); !ok { + if ok, _ := regexp.MatchString(`^ *(|~>|[<>!=]=) *\d`, inst.BundlerVersion); !ok { fmt.Fprintf(stderr, "invalid argument %q for -bundler-version\n", inst.BundlerVersion) return 2 } @@ -351,7 +351,7 @@ make install if [[ "$rubyversion" > "3" ]]; then /var/lib/arvados/bin/gem update --no-document --system 3.4.21 fi -/var/lib/arvados/bin/gem install bundler:`+inst.BundlerVersion+` --no-document +/var/lib/arvados/bin/gem install --conservative --no-document --version '`+inst.BundlerVersion+`' bundler `, stdout, stderr) if err != nil { return 1 @@ -901,7 +901,6 @@ func prodpkgs(osv osversion) []string { "curl", "fuse", "git", - "gitolite3", "graphviz", "haveged", "libcurl3-gnutls", diff --git a/lib/install/init.go b/lib/install/init.go index d9b74f6a06..12ffdd7af3 100644 --- a/lib/install/init.go +++ b/lib/install/init.go @@ -230,10 +230,6 @@ func (initcmd *initCommand) RunCommand(prog string, args []string, stdin io.Read Keepbalance: InternalURLs: "http://0.0.0.0:9019/": {} - GitHTTP: - InternalURLs: - "http://0.0.0.0:9005/": {} - ExternalURL: {{printf "%q" ( print "https://" .Domain ":4445/" ) }} DispatchCloud: InternalURLs: "http://0.0.0.0:9006/": {} diff --git a/lib/service/cmd.go b/lib/service/cmd.go index 82e95fe0b4..9ed0acfb8f 100644 --- a/lib/service/cmd.go +++ b/lib/service/cmd.go @@ -80,9 +80,9 @@ func (c *command) RunCommand(prog string, args []string, stdin io.Reader, stdout loader := config.NewLoader(stdin, log) loader.SetupFlags(flags) - // prog is [keepstore, keep-web, git-httpd, ...] but the + // prog is [keepstore, keep-web, ...] but the // legacy config flags are [-legacy-keepstore-config, - // -legacy-keepweb-config, -legacy-git-httpd-config, ...] + // -legacy-keepweb-config, ...] legacyFlag := "-legacy-" + strings.Replace(prog, "keep-", "keep", 1) + "-config" args = loader.MungeLegacyConfigArgs(log, args, legacyFlag) diff --git a/sdk/cwl/arvados_cwl/__init__.py b/sdk/cwl/arvados_cwl/__init__.py index 7e13488758..30d91b4094 100644 --- a/sdk/cwl/arvados_cwl/__init__.py +++ b/sdk/cwl/arvados_cwl/__init__.py @@ -6,9 +6,6 @@ # Implement cwl-runner interface for submitting and running work on Arvados, using # the Crunch containers API. -from future.utils import viewitems -from builtins import str - import argparse import importlib.metadata import importlib.resources @@ -333,7 +330,7 @@ def main(args=sys.argv[1:], add_arv_hints() - for key, val in viewitems(cwltool.argparser.get_default_args()): + for key, val in cwltool.argparser.get_default_args().items(): if not hasattr(arvargs, key): setattr(arvargs, key, val) diff --git a/sdk/cwl/arvados_cwl/arvcontainer.py b/sdk/cwl/arvados_cwl/arvcontainer.py index c3b914ba99..34b79d67b4 100644 --- a/sdk/cwl/arvados_cwl/arvcontainer.py +++ b/sdk/cwl/arvados_cwl/arvcontainer.py @@ -2,10 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from builtins import str - import logging import json import os diff --git a/sdk/cwl/arvados_cwl/arvworkflow.py b/sdk/cwl/arvados_cwl/arvworkflow.py index c592b83dc7..dae68459bc 100644 --- a/sdk/cwl/arvados_cwl/arvworkflow.py +++ b/sdk/cwl/arvados_cwl/arvworkflow.py @@ -2,18 +2,15 @@ # # SPDX-License-Identifier: Apache-2.0 -from past.builtins import basestring -from future.utils import viewitems - import os import json import copy import logging import urllib -from io import StringIO import sys import re +from io import StringIO from typing import (MutableSequence, MutableMapping) from ruamel.yaml import YAML @@ -588,7 +585,7 @@ class ArvadosWorkflowStep(WorkflowStep): runtimeContext = runtimeContext.copy() runtimeContext.toplevel = True # Preserve behavior for #13365 - builder = make_builder({shortname(k): v for k,v in viewitems(joborder)}, self.hints, self.requirements, + builder = make_builder({shortname(k): v for k, v in joborder.items()}, self.hints, self.requirements, runtimeContext, self.metadata) runtimeContext = set_cluster_target(self.tool, self.arvrunner, builder, runtimeContext) return super(ArvadosWorkflowStep, self).job(joborder, output_callback, runtimeContext) @@ -655,7 +652,7 @@ class ArvadosWorkflow(Workflow): dyn = False for k in max_res_pars + sum_res_pars: if k in req: - if isinstance(req[k], basestring): + if isinstance(req[k], str): if item["id"] == "#main": # only the top-level requirements/hints may contain expressions self.dynamic_resource_req.append(req) diff --git a/sdk/cwl/arvados_cwl/done.py b/sdk/cwl/arvados_cwl/done.py index 5c12419765..98c9f3a5df 100644 --- a/sdk/cwl/arvados_cwl/done.py +++ b/sdk/cwl/arvados_cwl/done.py @@ -2,11 +2,10 @@ # # SPDX-License-Identifier: Apache-2.0 -from future.utils import viewvalues - import re -from cwltool.errors import WorkflowException + from collections import deque +from cwltool.errors import WorkflowException def done(self, record, tmpdir, outdir, keepdir): cols = [ diff --git a/sdk/cwl/arvados_cwl/executor.py b/sdk/cwl/arvados_cwl/executor.py index 432b380aab..240e014e5a 100644 --- a/sdk/cwl/arvados_cwl/executor.py +++ b/sdk/cwl/arvados_cwl/executor.py @@ -2,12 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import division -from builtins import next -from builtins import object -from builtins import str -from future.utils import viewvalues, viewitems - import argparse import logging import os @@ -421,7 +415,7 @@ The 'jobs' API is no longer supported. if obj.get("class") == "InplaceUpdateRequirement": if obj["inplaceUpdate"] and parentfield == "requirements": raise SourceLine(obj, "class", UnsupportedRequirement).makeError("InplaceUpdateRequirement not supported for keep collections.") - for k,v in viewitems(obj): + for k,v in obj.items(): self.check_features(v, parentfield=k) elif isinstance(obj, list): for i,v in enumerate(obj): diff --git a/sdk/cwl/arvados_cwl/fsaccess.py b/sdk/cwl/arvados_cwl/fsaccess.py index a5e9db0cfe..a88380b468 100644 --- a/sdk/cwl/arvados_cwl/fsaccess.py +++ b/sdk/cwl/arvados_cwl/fsaccess.py @@ -2,12 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from builtins import object -from builtins import str -from future.utils import viewvalues - import fnmatch import os import errno @@ -314,7 +308,7 @@ def collectionResolver(api_client, document_loader, uri, num_retries=4): if pipeline_template_uuid_pattern.match(uri): pt = api_client.pipeline_templates().get(uuid=uri).execute(num_retries=num_retries) - return u"keep:" + viewvalues(pt["components"])[0]["script_parameters"]["cwl:tool"] + return u"keep:" + next(pt["components"].values())["script_parameters"]["cwl:tool"] p = uri.split("/") if arvados.util.keep_locator_pattern.match(p[0]): diff --git a/sdk/cwl/arvados_cwl/pathmapper.py b/sdk/cwl/arvados_cwl/pathmapper.py index 448facf776..ac6df543ad 100644 --- a/sdk/cwl/arvados_cwl/pathmapper.py +++ b/sdk/cwl/arvados_cwl/pathmapper.py @@ -2,12 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from builtins import str -from past.builtins import basestring -from future.utils import viewitems - import re import logging import uuid @@ -72,7 +66,7 @@ class ArvPathMapper(PathMapper): debug = logger.isEnabledFor(logging.DEBUG) - if isinstance(src, basestring) and src.startswith("keep:"): + if isinstance(src, str) and src.startswith("keep:"): if collection_pdh_pattern.match(src): self._pathmap[src] = MapperEnt(src, self.collection_pattern % urllib.parse.unquote(src[5:]), srcobj["class"], True) @@ -346,7 +340,7 @@ class StagingPathMapper(PathMapper): # Overridden to maintain the use case of mapping by source (identifier) to # target regardless of how the map is structured interally. def getMapperEnt(src): - for k,v in viewitems(self._pathmap): + for k,v in self._pathmap.items(): if (v.type != "CreateFile" and v.resolved == src) or (v.type == "CreateFile" and k == src): return v @@ -365,7 +359,7 @@ class VwdPathMapper(StagingPathMapper): # with any secondary files. self.visitlisting(referenced_files, self.stagedir, basedir) - for path, (ab, tgt, type, staged) in viewitems(self._pathmap): + for path, (ab, tgt, type, staged) in self._pathmap.items(): if type in ("File", "Directory") and ab.startswith("keep:"): self._pathmap[path] = MapperEnt("$(task.keep)/%s" % ab[5:], tgt, type, staged) diff --git a/sdk/cwl/arvados_cwl/perf.py b/sdk/cwl/arvados_cwl/perf.py index cc3ea969df..39f475fe8d 100644 --- a/sdk/cwl/arvados_cwl/perf.py +++ b/sdk/cwl/arvados_cwl/perf.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import object - import time import uuid diff --git a/sdk/cwl/arvados_cwl/runner.py b/sdk/cwl/arvados_cwl/runner.py index 437aa39eb8..259294a36e 100644 --- a/sdk/cwl/arvados_cwl/runner.py +++ b/sdk/cwl/arvados_cwl/runner.py @@ -2,11 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from future.utils import viewvalues, viewitems -from past.builtins import basestring - import os import sys import re @@ -72,6 +67,7 @@ from . import done from . context import ArvRuntimeContext from .perf import Perf +basestring = (bytes, str) logger = logging.getLogger('arvados.cwl-runner') metrics = logging.getLogger('arvados.cwl-runner.metrics') @@ -103,7 +99,7 @@ def find_defaults(d, op): if "default" in d: op(d) else: - for i in viewvalues(d): + for i in d.values(): find_defaults(i, op) def make_builder(joborder, hints, requirements, runtimeContext, metadata): @@ -567,7 +563,7 @@ def packed_workflow(arvrunner, tool, merged_map, runtimeContext, git_info): rewrite_out=rewrites, loader=tool.doc_loader) - rewrite_to_orig = {v: k for k,v in viewitems(rewrites)} + rewrite_to_orig = {v: k for k,v in rewrites.items()} def visit(v, cur_id): if isinstance(v, dict): diff --git a/sdk/cwl/arvados_version.py b/sdk/cwl/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/sdk/cwl/arvados_version.py +++ b/sdk/cwl/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/sdk/cwl/pytest.ini b/sdk/cwl/pytest.ini new file mode 120000 index 0000000000..05a82dbfef --- /dev/null +++ b/sdk/cwl/pytest.ini @@ -0,0 +1 @@ +../../sdk/python/pytest.ini \ No newline at end of file diff --git a/sdk/cwl/setup.py b/sdk/cwl/setup.py index 551bd964b1..5d8486f64f 100644 --- a/sdk/cwl/setup.py +++ b/sdk/cwl/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import os import sys @@ -33,9 +32,6 @@ setup(name='arvados-cwl-runner', 'cwltool==3.1.20230601100705', 'schema-salad==8.4.20230601112322', 'ciso8601 >= 2.0.0', - 'networkx < 2.6', - 'msgpack==1.0.3', - 'importlib-metadata<5', 'setuptools>=40.3.0', ], data_files=[ @@ -46,8 +42,5 @@ setup(name='arvados-cwl-runner', 'Programming Language :: Python :: 3', ], test_suite='tests', - tests_require=[ - 'mock>=1.0,<4', - ], zip_safe=True, ) diff --git a/sdk/cwl/tests/federation/framework/check_exist.py b/sdk/cwl/tests/federation/framework/check_exist.py index 1458772a3f..b3338939ed 100644 --- a/sdk/cwl/tests/federation/framework/check_exist.py +++ b/sdk/cwl/tests/federation/framework/check_exist.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function import arvados import json diff --git a/sdk/cwl/tests/federation/framework/prepare.py b/sdk/cwl/tests/federation/framework/prepare.py index 40bb843b29..6fe90813e7 100644 --- a/sdk/cwl/tests/federation/framework/prepare.py +++ b/sdk/cwl/tests/federation/framework/prepare.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function import arvados import json diff --git a/sdk/cwl/tests/hw.py b/sdk/cwl/tests/hw.py index e45bd72642..43c20dc03d 100644 --- a/sdk/cwl/tests/hw.py +++ b/sdk/cwl/tests/hw.py @@ -2,5 +2,4 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function print("Hello world") diff --git a/sdk/cwl/tests/matcher.py b/sdk/cwl/tests/matcher.py index 04e67b7dbd..3c49b87a86 100644 --- a/sdk/cwl/tests/matcher.py +++ b/sdk/cwl/tests/matcher.py @@ -2,13 +2,10 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import object - import difflib import json import re - class JsonDiffMatcher(object): """Raise AssertionError with a readable JSON diff when not __eq__(). diff --git a/sdk/cwl/tests/test_container.py b/sdk/cwl/tests/test_container.py index b95b8eb67b..885ee165b0 100644 --- a/sdk/cwl/tests/test_container.py +++ b/sdk/cwl/tests/test_container.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import str -from builtins import object - import arvados_cwl import arvados_cwl.context import arvados_cwl.util @@ -12,7 +9,6 @@ import arvados_cwl.util import copy import arvados.config import logging -import mock import unittest import os import functools @@ -25,6 +21,8 @@ from schema_salad.ref_resolver import Loader from schema_salad.sourceline import cmap import io +from unittest import mock + from .matcher import JsonDiffMatcher, StripYAMLComments from .mock_discovery import get_rootDesc diff --git a/sdk/cwl/tests/test_copy_deps.py b/sdk/cwl/tests/test_copy_deps.py index 28a5915b11..8ad735fddc 100644 --- a/sdk/cwl/tests/test_copy_deps.py +++ b/sdk/cwl/tests/test_copy_deps.py @@ -73,7 +73,7 @@ def check_contents(group, wf_uuid): raise Exception("Couldn't find collection containing expected "+expect_file) -def test_create(): +def check_create(): group = api.groups().create(body={"group": {"name": "test-19070-project-1", "group_class": "project"}}, ensure_unique_name=True).execute() try: contents = api.groups().contents(uuid=group["uuid"]).execute() @@ -90,7 +90,7 @@ def test_create(): api.groups().delete(uuid=group["uuid"]).execute() -def test_update(): +def check_update(): group = api.groups().create(body={"group": {"name": "test-19070-project-2", "group_class": "project"}}, ensure_unique_name=True).execute() try: contents = api.groups().contents(uuid=group["uuid"]).execute() @@ -132,7 +132,7 @@ def test_update(): api.groups().delete(uuid=group["uuid"]).execute() -def test_execute(): +def check_execute(): group = api.groups().create(body={"group": {"name": "test-19070-project-3", "group_class": "project"}}, ensure_unique_name=True).execute() try: contents = api.groups().contents(uuid=group["uuid"]).execute() @@ -193,6 +193,6 @@ def test_execute(): api.groups().delete(uuid=group["uuid"]).execute() if __name__ == '__main__': - test_create() - test_update() - test_execute() + check_create() + check_update() + check_execute() diff --git a/sdk/cwl/tests/test_fsaccess.py b/sdk/cwl/tests/test_fsaccess.py index f83612a8b0..c086f0e832 100644 --- a/sdk/cwl/tests/test_fsaccess.py +++ b/sdk/cwl/tests/test_fsaccess.py @@ -3,13 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 import functools -import mock import sys import unittest import json import logging import os +from unittest import mock + import arvados import arvados.keep import arvados.collection diff --git a/sdk/cwl/tests/test_make_output.py b/sdk/cwl/tests/test_make_output.py index dd1da0b524..eb39d801fe 100644 --- a/sdk/cwl/tests/test_make_output.py +++ b/sdk/cwl/tests/test_make_output.py @@ -2,17 +2,15 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() - import functools import json import logging -import mock import os import io import unittest +from unittest import mock + import arvados import arvados_cwl import arvados_cwl.executor diff --git a/sdk/cwl/tests/test_pathmapper.py b/sdk/cwl/tests/test_pathmapper.py index 194092db7a..1a13fc7079 100644 --- a/sdk/cwl/tests/test_pathmapper.py +++ b/sdk/cwl/tests/test_pathmapper.py @@ -3,13 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 import functools -import mock import sys import unittest import json import logging import os +from unittest import mock + import arvados import arvados.keep import arvados.collection diff --git a/sdk/cwl/tests/test_set_output_prop.py b/sdk/cwl/tests/test_set_output_prop.py index 3219eac989..0e829eeb92 100644 --- a/sdk/cwl/tests/test_set_output_prop.py +++ b/sdk/cwl/tests/test_set_output_prop.py @@ -7,7 +7,7 @@ import subprocess api = arvados.api() -def test_execute(): +def check_execute(): group = api.groups().create(body={"group": {"name": "test-17004-project", "group_class": "project"}}, ensure_unique_name=True).execute() try: contents = api.groups().contents(uuid=group["uuid"]).execute() @@ -34,4 +34,4 @@ def test_execute(): api.groups().delete(uuid=group["uuid"]).execute() if __name__ == '__main__': - test_execute() + check_execute() diff --git a/sdk/cwl/tests/test_submit.py b/sdk/cwl/tests/test_submit.py index c8bf127951..5f5fffb465 100644 --- a/sdk/cwl/tests/test_submit.py +++ b/sdk/cwl/tests/test_submit.py @@ -2,12 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from builtins import object -from builtins import str -from future.utils import viewvalues - import copy import io import itertools @@ -15,23 +9,14 @@ import functools import hashlib import json import logging -import mock import sys import unittest import cwltool.process import re import os -from io import BytesIO - -# StringIO.StringIO and io.StringIO have different behavior write() is -# called with both python2 (byte) strings and unicode strings -# (specifically there's some logging in cwltool that causes trouble). -# This isn't a problem on python3 because all string are unicode. -if sys.version_info[0] < 3: - from StringIO import StringIO -else: - from io import StringIO +from io import BytesIO, StringIO +from unittest import mock import arvados import arvados.collection @@ -142,7 +127,7 @@ def stubs(wfdetails=('submit_wf.cwl', None)): return CollectionExecute(created_collections[uuid]) def collection_getstub(created_collections, uuid): - for v in viewvalues(created_collections): + for v in created_collections.values(): if uuid in (v["uuid"], v["portable_data_hash"]): return CollectionExecute(v) diff --git a/sdk/cwl/tests/test_tq.py b/sdk/cwl/tests/test_tq.py index 05e5116d72..bf53f8912e 100644 --- a/sdk/cwl/tests/test_tq.py +++ b/sdk/cwl/tests/test_tq.py @@ -3,7 +3,6 @@ # SPDX-License-Identifier: Apache-2.0 import functools -import mock import sys import unittest import json @@ -11,6 +10,8 @@ import logging import os import threading +from unittest import mock + from cwltool.task_queue import TaskQueue def success_task(): diff --git a/sdk/cwl/tests/test_urljoin.py b/sdk/cwl/tests/test_urljoin.py index 86a053ea48..08bca55e3d 100644 --- a/sdk/cwl/tests/test_urljoin.py +++ b/sdk/cwl/tests/test_urljoin.py @@ -3,13 +3,14 @@ # SPDX-License-Identifier: Apache-2.0 import functools -import mock import sys import unittest import json import logging import os +from unittest import mock + import arvados import arvados.keep import arvados.collection diff --git a/sdk/cwl/tests/test_util.py b/sdk/cwl/tests/test_util.py index bf3d6fe0ef..9e94ec42f9 100644 --- a/sdk/cwl/tests/test_util.py +++ b/sdk/cwl/tests/test_util.py @@ -2,12 +2,11 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import bytes - -import unittest -import mock import datetime import httplib2 +import unittest + +from unittest import mock from arvados_cwl.util import * from arvados.errors import ApiError diff --git a/sdk/cwl/tests/wf/check_mem.py b/sdk/cwl/tests/wf/check_mem.py index b4322a8093..8cc4d6fb91 100644 --- a/sdk/cwl/tests/wf/check_mem.py +++ b/sdk/cwl/tests/wf/check_mem.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import division - import arvados import sys import os diff --git a/sdk/go/arvados/api.go b/sdk/go/arvados/api.go index c3d0ea8aef..dd1a6c4c32 100644 --- a/sdk/go/arvados/api.go +++ b/sdk/go/arvados/api.go @@ -42,11 +42,6 @@ var ( EndpointCollectionDelete = APIEndpoint{"DELETE", "arvados/v1/collections/{uuid}", ""} EndpointCollectionTrash = APIEndpoint{"POST", "arvados/v1/collections/{uuid}/trash", ""} EndpointCollectionUntrash = APIEndpoint{"POST", "arvados/v1/collections/{uuid}/untrash", ""} - EndpointSpecimenCreate = APIEndpoint{"POST", "arvados/v1/specimens", "specimen"} - EndpointSpecimenUpdate = APIEndpoint{"PATCH", "arvados/v1/specimens/{uuid}", "specimen"} - EndpointSpecimenGet = APIEndpoint{"GET", "arvados/v1/specimens/{uuid}", ""} - EndpointSpecimenList = APIEndpoint{"GET", "arvados/v1/specimens", ""} - EndpointSpecimenDelete = APIEndpoint{"DELETE", "arvados/v1/specimens/{uuid}", ""} EndpointContainerCreate = APIEndpoint{"POST", "arvados/v1/containers", "container"} EndpointContainerUpdate = APIEndpoint{"PATCH", "arvados/v1/containers/{uuid}", "container"} EndpointContainerPriorityUpdate = APIEndpoint{"POST", "arvados/v1/containers/{uuid}/update_priority", "container"} @@ -332,11 +327,6 @@ type API interface { LogGet(ctx context.Context, options GetOptions) (Log, error) LogList(ctx context.Context, options ListOptions) (LogList, error) LogDelete(ctx context.Context, options DeleteOptions) (Log, error) - SpecimenCreate(ctx context.Context, options CreateOptions) (Specimen, error) - SpecimenUpdate(ctx context.Context, options UpdateOptions) (Specimen, error) - SpecimenGet(ctx context.Context, options GetOptions) (Specimen, error) - SpecimenList(ctx context.Context, options ListOptions) (SpecimenList, error) - SpecimenDelete(ctx context.Context, options DeleteOptions) (Specimen, error) SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error) UserCreate(ctx context.Context, options CreateOptions) (User, error) UserUpdate(ctx context.Context, options UpdateOptions) (User, error) diff --git a/sdk/go/arvados/client.go b/sdk/go/arvados/client.go index 7bc3d5bc42..09185d1d6b 100644 --- a/sdk/go/arvados/client.go +++ b/sdk/go/arvados/client.go @@ -32,6 +32,7 @@ import ( "git.arvados.org/arvados.git/sdk/go/httpserver" "github.com/hashicorp/go-retryablehttp" + "github.com/sirupsen/logrus" ) // A Client is an HTTP client with an API endpoint and a set of @@ -82,6 +83,9 @@ type Client struct { // filesystem size. DiskCacheSize ByteSizeOrPercent + // Where to write debug logs. May be nil. + Logger logrus.FieldLogger + dd *DiscoveryDocument defaultRequestID string diff --git a/sdk/go/arvados/collection.go b/sdk/go/arvados/collection.go index 389fe4e484..1e9616c428 100644 --- a/sdk/go/arvados/collection.go +++ b/sdk/go/arvados/collection.go @@ -104,28 +104,57 @@ type CollectionList struct { Limit int `json:"limit"` } -var ( - blkRe = regexp.MustCompile(`^ [0-9a-f]{32}\+\d+`) - tokRe = regexp.MustCompile(` ?[^ ]*`) -) - // PortableDataHash computes the portable data hash of the given // manifest. func PortableDataHash(mt string) string { + // To calculate the PDH, we write the manifest to an md5 hash + // func, except we skip the "extra" part of block tokens that + // look like "abcdef0123456789abcdef0123456789+12345+extra". + // + // This code is simplified by the facts that (A) all block + // tokens -- even the first and last in a stream -- are + // preceded and followed by a space character; and (B) all + // non-block tokens either start with '.' or contain ':'. + // + // A regexp-based approach (like the one this replaced) would + // be more readable, but very slow. h := md5.New() size := 0 - _ = tokRe.ReplaceAllFunc([]byte(mt), func(tok []byte) []byte { - if m := blkRe.Find(tok); m != nil { - // write hash+size, ignore remaining block hints - tok = m + todo := []byte(mt) + for len(todo) > 0 { + // sp is the end of the current token (note that if + // the current token is the last file token in a + // stream, we'll also include the \n and the dirname + // token on the next line, which is perfectly fine for + // our purposes). + sp := bytes.IndexByte(todo, ' ') + if sp < 0 { + // Last token of the manifest, which is never + // a block token. + n, _ := h.Write(todo) + size += n + break } - n, err := h.Write(tok) - if err != nil { - panic(err) + if sp >= 34 && todo[32] == '+' && bytes.IndexByte(todo[:32], ':') == -1 && todo[0] != '.' { + // todo[:sp] is a block token. + sizeend := bytes.IndexByte(todo[33:sp], '+') + if sizeend < 0 { + // "hash+size" + sizeend = sp + } else { + // "hash+size+extra" + sizeend += 33 + } + n, _ := h.Write(todo[:sizeend]) + h.Write([]byte{' '}) + size += n + 1 + } else { + // todo[:sp] is not a block token. + n, _ := h.Write(todo[:sp+1]) + size += n } - size += n - return nil - }) + todo = todo[sp+1:] + } return fmt.Sprintf("%x+%d", h.Sum(nil), size) } diff --git a/sdk/go/arvados/config.go b/sdk/go/arvados/config.go index 116051b09e..8572613e94 100644 --- a/sdk/go/arvados/config.go +++ b/sdk/go/arvados/config.go @@ -161,11 +161,6 @@ type Cluster struct { WebDAVLogEvents bool WebDAVOutputBuffer ByteSize } - Git struct { - GitCommand string - GitoliteHome string - Repositories string - } Login struct { LDAP struct { Enable bool @@ -248,7 +243,6 @@ type Cluster struct { AutoAdminFirstUser bool AutoAdminUserWithEmail string AutoSetupNewUsers bool - AutoSetupNewUsersWithRepository bool AutoSetupNewUsersWithVmUUID string AutoSetupUsernameBlacklist StringSet EmailSubjectPrefix string @@ -356,8 +350,6 @@ type Services struct { DispatchCloud Service DispatchLSF Service DispatchSLURM Service - GitHTTP Service - GitSSH Service Health Service Keepbalance Service Keepproxy Service @@ -511,21 +503,11 @@ type ContainersConfig struct { LocalKeepLogsToContainerLog string JobsAPI struct { - Enable string - GitInternalDir string + Enable string } Logging struct { - MaxAge Duration - SweepInterval Duration - LogBytesPerEvent int - LogSecondsBetweenEvents Duration - LogThrottlePeriod Duration - LogThrottleBytes int - LogThrottleLines int - LimitLogBytesPerJob int - LogPartialLineThrottlePeriod Duration - LogUpdatePeriod Duration - LogUpdateSize ByteSize + LogUpdatePeriod Duration + LogUpdateSize ByteSize } ShellAccess struct { Admin bool @@ -535,15 +517,6 @@ type ContainersConfig struct { PrioritySpread int64 SbatchArgumentsList []string SbatchEnvironmentVariables map[string]string - Managed struct { - DNSServerConfDir string - DNSServerConfTemplate string - DNSServerReloadCommand string - DNSServerUpdateCommand string - ComputeNodeDomain string - ComputeNodeNameservers StringSet - AssignNodeHostname string - } } LSF struct { BsubSudoUser string @@ -670,7 +643,6 @@ const ( ServiceNameDispatchCloud ServiceName = "arvados-dispatch-cloud" ServiceNameDispatchLSF ServiceName = "arvados-dispatch-lsf" ServiceNameDispatchSLURM ServiceName = "crunch-dispatch-slurm" - ServiceNameGitHTTP ServiceName = "arvados-git-httpd" ServiceNameHealth ServiceName = "arvados-health" ServiceNameKeepbalance ServiceName = "keep-balance" ServiceNameKeepproxy ServiceName = "keepproxy" @@ -690,7 +662,6 @@ func (svcs Services) Map() map[ServiceName]Service { ServiceNameDispatchCloud: svcs.DispatchCloud, ServiceNameDispatchLSF: svcs.DispatchLSF, ServiceNameDispatchSLURM: svcs.DispatchSLURM, - ServiceNameGitHTTP: svcs.GitHTTP, ServiceNameHealth: svcs.Health, ServiceNameKeepbalance: svcs.Keepbalance, ServiceNameKeepproxy: svcs.Keepproxy, diff --git a/sdk/go/arvados/container.go b/sdk/go/arvados/container.go index 91c8fbfe29..70038a18f7 100644 --- a/sdk/go/arvados/container.go +++ b/sdk/go/arvados/container.go @@ -23,6 +23,7 @@ type Container struct { Mounts map[string]Mount `json:"mounts"` Output string `json:"output"` OutputPath string `json:"output_path"` + OutputGlob []string `json:"output_glob"` Priority int64 `json:"priority"` RuntimeConstraints RuntimeConstraints `json:"runtime_constraints"` State ContainerState `json:"state"` @@ -68,6 +69,7 @@ type ContainerRequest struct { Cwd string `json:"cwd"` Command []string `json:"command"` OutputPath string `json:"output_path"` + OutputGlob []string `json:"output_glob"` OutputName string `json:"output_name"` OutputTTL int `json:"output_ttl"` Priority int `json:"priority"` @@ -94,9 +96,6 @@ type Mount struct { Content interface{} `json:"content"` ExcludeFromOutput bool `json:"exclude_from_output"` Capacity int64 `json:"capacity"` - Commit string `json:"commit"` // only if kind=="git_tree" - RepositoryName string `json:"repository_name"` // only if kind=="git_tree" - GitURL string `json:"git_url"` // only if kind=="git_tree" } type CUDARuntimeConstraints struct { diff --git a/sdk/go/arvados/fs_collection.go b/sdk/go/arvados/fs_collection.go index 052cc1aa37..101fade74b 100644 --- a/sdk/go/arvados/fs_collection.go +++ b/sdk/go/arvados/fs_collection.go @@ -1358,6 +1358,10 @@ func (dn *dirnode) loadManifest(txt string) error { } streams = streams[:len(streams)-1] segments := []storedSegment{} + // streamoffset[n] is the position in the stream of the nth + // block, i.e., ∑ segments[j].size ∀ 0≤j offset { - // Can't continue where we left off. - // TODO: binary search instead of - // rewinding all the way (but this - // situation might be rare anyway) - segIdx, pos = 0, 0 + if segIdx < len(segments) && streamoffset[segIdx] <= offset && streamoffset[segIdx+1] > offset { + // common case with an easy + // optimization: start where the + // previous segment ended + } else if guess := int(offset >> 26); guess >= 0 && guess < len(segments) && streamoffset[guess] <= offset && streamoffset[guess+1] > offset { + // another common case with an easy + // optimization: all blocks are 64 MiB + // (or close enough) + segIdx = guess + } else { + // general case + segIdx = sort.Search(len(segments), func(i int) bool { + return streamoffset[i+1] > offset + }) } for ; segIdx < len(segments); segIdx++ { - seg := segments[segIdx] - next := pos + int64(seg.Len()) - if next <= offset || seg.Len() == 0 { - pos = next - continue - } - if pos >= offset+length { + blkStart := streamoffset[segIdx] + if blkStart >= offset+length { break } + seg := &segments[segIdx] + if seg.size == 0 { + continue + } var blkOff int - if pos < offset { - blkOff = int(offset - pos) + if blkStart < offset { + blkOff = int(offset - blkStart) } - blkLen := seg.Len() - blkOff - if pos+int64(blkOff+blkLen) > offset+length { - blkLen = int(offset + length - pos - int64(blkOff)) + blkLen := seg.size - blkOff + if blkStart+int64(seg.size) > offset+length { + blkLen = int(offset + length - blkStart - int64(blkOff)) } fnode.appendSegment(storedSegment{ kc: dn.fs, @@ -1482,14 +1503,9 @@ func (dn *dirnode) loadManifest(txt string) error { offset: blkOff, length: blkLen, }) - if next > offset+length { - break - } else { - pos = next - } } - if segIdx == len(segments) && pos < offset+length { - return fmt.Errorf("line %d: invalid segment in %d-byte stream: %q", lineno, pos, token) + if segIdx == len(segments) && streamoffset[segIdx] < offset+length { + return fmt.Errorf("line %d: invalid segment in %d-byte stream: %q", lineno, streamoffset[segIdx], token) } } if !anyFileTokens { diff --git a/sdk/go/arvados/fs_collection_test.go b/sdk/go/arvados/fs_collection_test.go index a29371b76c..b57f9aa30f 100644 --- a/sdk/go/arvados/fs_collection_test.go +++ b/sdk/go/arvados/fs_collection_test.go @@ -1639,29 +1639,71 @@ type CollectionFSUnitSuite struct{} var _ = check.Suite(&CollectionFSUnitSuite{}) // expect ~2 seconds to load a manifest with 256K files -func (s *CollectionFSUnitSuite) TestLargeManifest(c *check.C) { +func (s *CollectionFSUnitSuite) TestLargeManifest_ManyFiles(c *check.C) { if testing.Short() { c.Skip("slow") } + s.testLargeManifest(c, 512, 512, 1, 0) +} - const ( - dirCount = 512 - fileCount = 512 - ) +func (s *CollectionFSUnitSuite) TestLargeManifest_LargeFiles(c *check.C) { + if testing.Short() { + c.Skip("slow") + } + s.testLargeManifest(c, 1, 800, 1000, 0) +} +func (s *CollectionFSUnitSuite) TestLargeManifest_InterleavedFiles(c *check.C) { + if testing.Short() { + c.Skip("slow") + } + // Timing figures here are from a dev host, (0)->(1)->(2)->(3) + // (0) no optimizations (main branch commit ea697fb1e8) + // (1) resolve streampos->blkidx with binary search + // (2) ...and rewrite PortableDataHash() without regexp + // (3) ...and use fnodeCache in loadManifest + s.testLargeManifest(c, 1, 800, 100, 4<<20) // 127s -> 12s -> 2.5s -> 1.5s + s.testLargeManifest(c, 1, 50, 1000, 4<<20) // 44s -> 10s -> 1.5s -> 0.8s + s.testLargeManifest(c, 1, 200, 100, 4<<20) // 13s -> 4s -> 0.6s -> 0.3s + s.testLargeManifest(c, 1, 200, 150, 4<<20) // 26s -> 4s -> 1s -> 0.5s + s.testLargeManifest(c, 1, 200, 200, 4<<20) // 38s -> 6s -> 1.3s -> 0.7s + s.testLargeManifest(c, 1, 200, 225, 4<<20) // 46s -> 7s -> 1.5s -> 1s + s.testLargeManifest(c, 1, 400, 400, 4<<20) // 477s -> 24s -> 5s -> 3s + // s.testLargeManifest(c, 1, 800, 1000, 4<<20) // timeout -> 186s -> 28s -> 17s +} + +func (s *CollectionFSUnitSuite) testLargeManifest(c *check.C, dirCount, filesPerDir, blocksPerFile, interleaveChunk int) { + t0 := time.Now() + const blksize = 1 << 26 + c.Logf("%s building manifest with dirCount=%d filesPerDir=%d blocksPerFile=%d", time.Now(), dirCount, filesPerDir, blocksPerFile) mb := bytes.NewBuffer(make([]byte, 0, 40000000)) + blkid := 0 for i := 0; i < dirCount; i++ { fmt.Fprintf(mb, "./dir%d", i) - for j := 0; j <= fileCount; j++ { - fmt.Fprintf(mb, " %032x+42+A%040x@%08x", j, j, j) + for j := 0; j < filesPerDir; j++ { + for k := 0; k < blocksPerFile; k++ { + blkid++ + fmt.Fprintf(mb, " %032x+%d+A%040x@%08x", blkid, blksize, blkid, blkid) + } } - for j := 0; j < fileCount; j++ { - fmt.Fprintf(mb, " %d:%d:dir%d/file%d", j*42+21, 42, j, j) + for j := 0; j < filesPerDir; j++ { + if interleaveChunk == 0 { + fmt.Fprintf(mb, " %d:%d:dir%d/file%d", (filesPerDir-j-1)*blocksPerFile*blksize, blocksPerFile*blksize, j, j) + continue + } + for todo := int64(blocksPerFile) * int64(blksize); todo > 0; todo -= int64(interleaveChunk) { + size := int64(interleaveChunk) + if size > todo { + size = todo + } + offset := rand.Int63n(int64(blocksPerFile)*int64(blksize)*int64(filesPerDir) - size) + fmt.Fprintf(mb, " %d:%d:dir%d/file%d", offset, size, j, j) + } } mb.Write([]byte{'\n'}) } coll := Collection{ManifestText: mb.String()} - c.Logf("%s built", time.Now()) + c.Logf("%s built manifest size=%d", time.Now(), mb.Len()) var memstats runtime.MemStats runtime.ReadMemStats(&memstats) @@ -1670,17 +1712,28 @@ func (s *CollectionFSUnitSuite) TestLargeManifest(c *check.C) { f, err := coll.FileSystem(NewClientFromEnv(), &keepClientStub{}) c.Check(err, check.IsNil) c.Logf("%s loaded", time.Now()) - c.Check(f.Size(), check.Equals, int64(42*dirCount*fileCount)) + c.Check(f.Size(), check.Equals, int64(dirCount*filesPerDir*blocksPerFile*blksize)) + // Stat() and OpenFile() each file. This mimics the behavior + // of webdav propfind, which opens each file even when just + // listing directory entries. for i := 0; i < dirCount; i++ { - for j := 0; j < fileCount; j++ { - f.Stat(fmt.Sprintf("./dir%d/dir%d/file%d", i, j, j)) + for j := 0; j < filesPerDir; j++ { + fnm := fmt.Sprintf("./dir%d/dir%d/file%d", i, j, j) + fi, err := f.Stat(fnm) + c.Assert(err, check.IsNil) + c.Check(fi.IsDir(), check.Equals, false) + f, err := f.OpenFile(fnm, os.O_RDONLY, 0) + c.Assert(err, check.IsNil) + f.Close() } } - c.Logf("%s Stat() x %d", time.Now(), dirCount*fileCount) + c.Logf("%s OpenFile() x %d", time.Now(), dirCount*filesPerDir) runtime.ReadMemStats(&memstats) c.Logf("%s Alloc=%d Sys=%d", time.Now(), memstats.Alloc, memstats.Sys) + c.Logf("%s MemorySize=%d", time.Now(), f.MemorySize()) + c.Logf("%s ... test duration %s", time.Now(), time.Now().Sub(t0)) } // Gocheck boilerplate diff --git a/sdk/go/arvados/keep_cache.go b/sdk/go/arvados/keep_cache.go index 108081d5ac..72a0031cac 100644 --- a/sdk/go/arvados/keep_cache.go +++ b/sdk/go/arvados/keep_cache.go @@ -113,7 +113,10 @@ func (cache *DiskCache) setup() { defer sharedCachesLock.Unlock() dir := cache.Dir if sharedCaches[dir] == nil { + cache.debugf("initializing sharedCache using %s with max size %d", dir, cache.MaxSize) sharedCaches[dir] = &sharedCache{dir: dir, maxSize: cache.MaxSize} + } else { + cache.debugf("using existing sharedCache using %s with max size %d (would have initialized with %d)", dir, sharedCaches[dir].maxSize, cache.MaxSize) } cache.sharedCache = sharedCaches[dir] } @@ -623,8 +626,9 @@ func (cache *DiskCache) tidy() { } var stat unix.Statfs_t if nil == unix.Statfs(cache.dir, &stat) { - maxsize = int64(stat.Bavail) * stat.Bsize * pct / 100 + maxsize = int64(stat.Blocks) * stat.Bsize * pct / 100 atomic.StoreInt64(&cache.defaultMaxSize, maxsize) + cache.debugf("setting cache size %d = blocks %d * bsize %d * pct %d / 100", maxsize, stat.Blocks, stat.Bsize, pct) } else { // In this case we will set // defaultMaxSize below after diff --git a/sdk/go/arvados/specimen.go b/sdk/go/arvados/specimen.go deleted file mode 100644 index b561fb20ae..0000000000 --- a/sdk/go/arvados/specimen.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: Apache-2.0 - -package arvados - -import "time" - -type Specimen struct { - UUID string `json:"uuid"` - OwnerUUID string `json:"owner_uuid"` - CreatedAt time.Time `json:"created_at"` - ModifiedAt time.Time `json:"modified_at"` - ModifiedByClientUUID string `json:"modified_by_client_uuid"` - ModifiedByUserUUID string `json:"modified_by_user_uuid"` - Properties map[string]interface{} `json:"properties"` -} - -type SpecimenList struct { - Items []Specimen `json:"items"` - ItemsAvailable int `json:"items_available"` - Offset int `json:"offset"` - Limit int `json:"limit"` -} diff --git a/sdk/go/arvadosclient/arvadosclient.go b/sdk/go/arvadosclient/arvadosclient.go index d0ebdc1b01..1f849ebace 100644 --- a/sdk/go/arvadosclient/arvadosclient.go +++ b/sdk/go/arvadosclient/arvadosclient.go @@ -20,6 +20,7 @@ import ( "time" "git.arvados.org/arvados.git/sdk/go/arvados" + "github.com/sirupsen/logrus" ) type StringMatcher func(string) bool @@ -110,6 +111,9 @@ type ArvadosClient struct { // filesystem size. DiskCacheSize arvados.ByteSizeOrPercent + // Where to write debug logs. May be nil. + Logger logrus.FieldLogger + // Discovery document DiscoveryDoc Dict @@ -150,6 +154,7 @@ func New(c *arvados.Client) (*ArvadosClient, error) { Retries: 2, KeepServiceURIs: c.KeepServiceURIs, DiskCacheSize: c.DiskCacheSize, + Logger: c.Logger, lastClosedIdlesAt: time.Now(), } diff --git a/sdk/go/arvadosclient/pool.go b/sdk/go/arvadosclient/pool.go index bb7867aef7..4272f0f759 100644 --- a/sdk/go/arvadosclient/pool.go +++ b/sdk/go/arvadosclient/pool.go @@ -13,8 +13,8 @@ import ( // A ClientPool is a pool of ArvadosClients. This is useful for // applications that make API calls using a dynamic set of tokens, // like web services that pass through their own clients' -// credentials. See arvados-git-httpd for an example, and sync.Pool -// for more information about garbage collection. +// credentials. See sync.Pool for more information about garbage +// collection. type ClientPool struct { // Initialize new clients by copying this one. Prototype *ArvadosClient diff --git a/sdk/go/arvadostest/api.go b/sdk/go/arvadostest/api.go index e1827b5d1f..658874c6d7 100644 --- a/sdk/go/arvadostest/api.go +++ b/sdk/go/arvadostest/api.go @@ -264,26 +264,6 @@ func (as *APIStub) LogDelete(ctx context.Context, options arvados.DeleteOptions) as.appendCall(ctx, as.LogDelete, options) return arvados.Log{}, as.Error } -func (as *APIStub) SpecimenCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Specimen, error) { - as.appendCall(ctx, as.SpecimenCreate, options) - return arvados.Specimen{}, as.Error -} -func (as *APIStub) SpecimenUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Specimen, error) { - as.appendCall(ctx, as.SpecimenUpdate, options) - return arvados.Specimen{}, as.Error -} -func (as *APIStub) SpecimenGet(ctx context.Context, options arvados.GetOptions) (arvados.Specimen, error) { - as.appendCall(ctx, as.SpecimenGet, options) - return arvados.Specimen{}, as.Error -} -func (as *APIStub) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) { - as.appendCall(ctx, as.SpecimenList, options) - return arvados.SpecimenList{}, as.Error -} -func (as *APIStub) SpecimenDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Specimen, error) { - as.appendCall(ctx, as.SpecimenDelete, options) - return arvados.Specimen{}, as.Error -} func (as *APIStub) SysTrashSweep(ctx context.Context, options struct{}) (struct{}, error) { as.appendCall(ctx, as.SysTrashSweep, options) return struct{}{}, as.Error diff --git a/sdk/go/arvadostest/fixtures.go b/sdk/go/arvadostest/fixtures.go index 3b8a618fea..c70af45b59 100644 --- a/sdk/go/arvadostest/fixtures.go +++ b/sdk/go/arvadostest/fixtures.go @@ -101,7 +101,7 @@ const ( AdminAuthorizedKeysUUID = "zzzzz-fngyi-12nc9ov4osp8nae" - CrunchstatForRunningJobLogUUID = "zzzzz-57u5n-tmymyrojrbtnxh1" + CrunchstatForRunningContainerLogUUID = "zzzzz-57u5n-containerlog006" IdleNodeUUID = "zzzzz-7ekkf-2z3mc76g2q73aio" diff --git a/sdk/go/health/aggregator_test.go b/sdk/go/health/aggregator_test.go index f76f7b8ea8..d9f3faf034 100644 --- a/sdk/go/health/aggregator_test.go +++ b/sdk/go/health/aggregator_test.go @@ -372,7 +372,6 @@ func (s *AggregatorSuite) setAllServiceURLs(listen string) { &svcs.DispatchCloud, &svcs.DispatchLSF, &svcs.DispatchSLURM, - &svcs.GitHTTP, &svcs.Keepbalance, &svcs.Keepproxy, &svcs.Keepstore, diff --git a/sdk/go/keepclient/discover.go b/sdk/go/keepclient/discover.go index 5eafbbe339..192d4738e6 100644 --- a/sdk/go/keepclient/discover.go +++ b/sdk/go/keepclient/discover.go @@ -102,7 +102,11 @@ func (ent *cachedSvcList) poll() { var next svcList err := ent.arv.Call("GET", "keep_services", "", "accessible", nil, &next) if err != nil { - log.Printf("WARNING: Error retrieving services list: %v (retrying in %v)", err, errDelay) + if ent.arv.Logger != nil { + ent.arv.Logger.WithError(err).Warnf("error retrieving services list (retrying in %v)", errDelay) + } else { + log.Printf("WARNING: Error retrieving services list: %s (retrying in %v)", err, errDelay) + } timer.Reset(errDelay) continue } diff --git a/sdk/go/keepclient/keepclient.go b/sdk/go/keepclient/keepclient.go index d97a2d1fcd..1c72e583cb 100644 --- a/sdk/go/keepclient/keepclient.go +++ b/sdk/go/keepclient/keepclient.go @@ -100,6 +100,8 @@ const ( XKeepReplicasStored = "X-Keep-Replicas-Stored" XKeepStorageClasses = "X-Keep-Storage-Classes" XKeepStorageClassesConfirmed = "X-Keep-Storage-Classes-Confirmed" + XKeepSignature = "X-Keep-Signature" + XKeepLocator = "X-Keep-Locator" ) type HTTPClient interface { @@ -209,8 +211,8 @@ func New(arv *arvadosclient.ArvadosClient) *KeepClient { Retries: 2, } err = kc.loadDefaultClasses() - if err != nil { - DebugPrintf("DEBUG: Unable to load the default storage classes cluster config") + if err != nil && arv.Logger != nil { + arv.Logger.WithError(err).Debug("unable to load the default storage classes cluster config") } return kc } @@ -370,7 +372,9 @@ func (kc *KeepClient) getOrHead(method string, locator string, header http.Heade time.Sleep(delay.Next()) } } - DebugPrintf("DEBUG: %s %s failed: %v", method, locator, errs) + if kc.Arvados.Logger != nil { + kc.Arvados.Logger.Debugf("DEBUG: %s %s failed: %v", method, locator, errs) + } var err error if count404 == numServers { @@ -418,6 +422,7 @@ func (kc *KeepClient) upstreamGateway() arvados.KeepGateway { Dir: cachedir, MaxSize: kc.DiskCacheSize, KeepGateway: backend, + Logger: kc.Arvados.Logger, } } return kc.gatewayStack @@ -725,6 +730,13 @@ func (kc *KeepClient) getRequestID() string { return reqIDGen.Next() } +func (kc *KeepClient) debugf(format string, args ...interface{}) { + if kc.Arvados.Logger == nil { + return + } + kc.Arvados.Logger.Debugf(format, args...) +} + type Locator struct { Hash string Size int // -1 if data size is not known diff --git a/sdk/go/keepclient/keepclient_test.go b/sdk/go/keepclient/keepclient_test.go index 531db31b25..fb59460c72 100644 --- a/sdk/go/keepclient/keepclient_test.go +++ b/sdk/go/keepclient/keepclient_test.go @@ -11,7 +11,6 @@ import ( "fmt" "io" "io/ioutil" - "log" "net" "net/http" "os" @@ -189,8 +188,6 @@ func UploadToStubHelper(c *C, st http.Handler, f func(*KeepClient, string, } func (s *StandaloneSuite) TestUploadToStubKeepServer(c *C) { - log.Printf("TestUploadToStubKeepServer") - st := &StubPutHandler{ c: c, expectPath: "acbd18db4cc2f85cedef654fccc4a4d8", diff --git a/sdk/go/keepclient/support.go b/sdk/go/keepclient/support.go index d3d799dc5d..142f1d2151 100644 --- a/sdk/go/keepclient/support.go +++ b/sdk/go/keepclient/support.go @@ -12,30 +12,16 @@ import ( "fmt" "io" "io/ioutil" - "log" "math/rand" "net/http" - "os" "strconv" "strings" "time" "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadosclient" "git.arvados.org/arvados.git/sdk/go/asyncbuf" ) -// DebugPrintf emits debug messages. The easiest way to enable -// keepclient debug messages in your application is to assign -// log.Printf to DebugPrintf. -var DebugPrintf = func(string, ...interface{}) {} - -func init() { - if arvadosclient.StringBool(os.Getenv("ARVADOS_DEBUG")) { - DebugPrintf = log.Printf - } -} - type keepService struct { Uuid string `json:"uuid"` Hostname string `json:"service_host"` @@ -70,7 +56,7 @@ func (kc *KeepClient) uploadToKeepServer(host string, hash string, classesTodo [ var err error var url = fmt.Sprintf("%s/%s", host, hash) if req, err = http.NewRequest("PUT", url, nil); err != nil { - DebugPrintf("DEBUG: [%s] Error creating request PUT %v error: %v", reqid, url, err.Error()) + kc.debugf("[%s] Error creating request: PUT %s error: %s", reqid, url, err) uploadStatusChan <- uploadStatus{err, url, 0, 0, nil, ""} return } @@ -94,7 +80,7 @@ func (kc *KeepClient) uploadToKeepServer(host string, hash string, classesTodo [ var resp *http.Response if resp, err = kc.httpClient().Do(req); err != nil { - DebugPrintf("DEBUG: [%s] Upload failed %v error: %v", reqid, url, err.Error()) + kc.debugf("[%s] Upload failed: %s error: %s", reqid, url, err) uploadStatusChan <- uploadStatus{err, url, 0, 0, nil, err.Error()} return } @@ -106,7 +92,7 @@ func (kc *KeepClient) uploadToKeepServer(host string, hash string, classesTodo [ scc := resp.Header.Get(XKeepStorageClassesConfirmed) classesStored, err := parseStorageClassesConfirmedHeader(scc) if err != nil { - DebugPrintf("DEBUG: [%s] Ignoring invalid %s header %q: %s", reqid, XKeepStorageClassesConfirmed, scc, err) + kc.debugf("[%s] Ignoring invalid %s header %q: %s", reqid, XKeepStorageClassesConfirmed, scc, err) } defer resp.Body.Close() @@ -115,16 +101,16 @@ func (kc *KeepClient) uploadToKeepServer(host string, hash string, classesTodo [ respbody, err2 := ioutil.ReadAll(&io.LimitedReader{R: resp.Body, N: 4096}) response := strings.TrimSpace(string(respbody)) if err2 != nil && err2 != io.EOF { - DebugPrintf("DEBUG: [%s] Upload %v error: %v response: %v", reqid, url, err2.Error(), response) + kc.debugf("[%s] Upload %s error: %s response: %s", reqid, url, err2, response) uploadStatusChan <- uploadStatus{err2, url, resp.StatusCode, rep, classesStored, response} } else if resp.StatusCode == http.StatusOK { - DebugPrintf("DEBUG: [%s] Upload %v success", reqid, url) + kc.debugf("[%s] Upload %s success", reqid, url) uploadStatusChan <- uploadStatus{nil, url, resp.StatusCode, rep, classesStored, response} } else { if resp.StatusCode >= 300 && response == "" { response = resp.Status } - DebugPrintf("DEBUG: [%s] Upload %v error: %v response: %v", reqid, url, resp.StatusCode, response) + kc.debugf("[%s] Upload %s status: %d %s", reqid, url, resp.StatusCode, response) uploadStatusChan <- uploadStatus{errors.New(resp.Status), url, resp.StatusCode, rep, classesStored, response} } } @@ -255,7 +241,7 @@ func (kc *KeepClient) httpBlockWrite(ctx context.Context, req arvados.BlockWrite for active*replicasPerThread < maxConcurrency { // Start some upload requests if nextServer < len(sv) { - DebugPrintf("DEBUG: [%s] Begin upload %s to %s", req.RequestID, req.Hash, sv[nextServer]) + kc.debugf("[%s] Begin upload %s to %s", req.RequestID, req.Hash, sv[nextServer]) go kc.uploadToKeepServer(sv[nextServer], req.Hash, classesTodo, getReader(), uploadStatusChan, req.DataSize, req.RequestID) nextServer++ active++ @@ -272,7 +258,7 @@ func (kc *KeepClient) httpBlockWrite(ctx context.Context, req arvados.BlockWrite } } - DebugPrintf("DEBUG: [%s] Replicas remaining to write: %v active uploads: %v", req.RequestID, replicasTodo, active) + kc.debugf("[%s] Replicas remaining to write: %d active uploads: %d", req.RequestID, replicasTodo, active) if active < 1 { break } diff --git a/sdk/python/arvados-v1-discovery.json b/sdk/python/arvados-v1-discovery.json index 232c88d067..ef187f6663 100644 --- a/sdk/python/arvados-v1-discovery.json +++ b/sdk/python/arvados-v1-discovery.json @@ -2952,17 +2952,17 @@ } } }, - "humans": { + "keep_services": { "methods": { "get": { - "id": "arvados.humans.get", - "path": "humans/{uuid}", + "id": "arvados.keep_services.get", + "path": "keep_services/{uuid}", "httpMethod": "GET", - "description": "Gets a Human's metadata by UUID.", + "description": "Gets a KeepService's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Human in question.", + "description": "The UUID of the KeepService in question.", "required": true, "location": "path" } @@ -2971,7 +2971,7 @@ "uuid" ], "response": { - "$ref": "Human" + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -2979,10 +2979,10 @@ ] }, "index": { - "id": "arvados.humans.list", - "path": "humans", + "id": "arvados.keep_services.list", + "path": "keep_services", "httpMethod": "GET", - "description": "List Humans.\n\n The list method returns a\n resource list of\n matching Humans. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#humanList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List KeepServices.\n\n The list method returns a\n resource list of\n matching KeepServices. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepServiceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -3050,7 +3050,7 @@ } }, "response": { - "$ref": "HumanList" + "$ref": "KeepServiceList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3058,10 +3058,10 @@ ] }, "create": { - "id": "arvados.humans.create", - "path": "humans", + "id": "arvados.keep_services.create", + "path": "keep_services", "httpMethod": "POST", - "description": "Create a new Human.", + "description": "Create a new KeepService.", "parameters": { "select": { "type": "array", @@ -3086,27 +3086,27 @@ "request": { "required": true, "properties": { - "human": { - "$ref": "Human" + "keep_service": { + "$ref": "KeepService" } } }, "response": { - "$ref": "Human" + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.humans.update", - "path": "humans/{uuid}", + "id": "arvados.keep_services.update", + "path": "keep_services/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing Human.", + "description": "Update attributes of an existing KeepService.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Human in question.", + "description": "The UUID of the KeepService in question.", "required": true, "location": "path" }, @@ -3120,43 +3120,56 @@ "request": { "required": true, "properties": { - "human": { - "$ref": "Human" + "keep_service": { + "$ref": "KeepService" } } }, "response": { - "$ref": "Human" + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.humans.delete", - "path": "humans/{uuid}", + "id": "arvados.keep_services.delete", + "path": "keep_services/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing Human.", + "description": "Delete an existing KeepService.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Human in question.", + "description": "The UUID of the KeepService in question.", "required": true, "location": "path" } }, "response": { - "$ref": "Human" + "$ref": "KeepService" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "accessible": { + "id": "arvados.keep_services.accessible", + "path": "keep_services/accessible", + "httpMethod": "GET", + "description": "accessible keep_services", + "parameters": {}, + "response": { + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "list": { - "id": "arvados.humans.list", - "path": "humans", + "id": "arvados.keep_services.list", + "path": "keep_services", "httpMethod": "GET", - "description": "List Humans.\n\n The list method returns a\n resource list of\n matching Humans. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#humanList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List KeepServices.\n\n The list method returns a\n resource list of\n matching KeepServices. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepServiceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -3224,7 +3237,7 @@ } }, "response": { - "$ref": "HumanList" + "$ref": "KeepServiceList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3232,10 +3245,10 @@ ] }, "show": { - "id": "arvados.humans.show", - "path": "humans/{uuid}", + "id": "arvados.keep_services.show", + "path": "keep_services/{uuid}", "httpMethod": "GET", - "description": "show humans", + "description": "show keep_services", "parameters": { "uuid": { "type": "string", @@ -3251,17 +3264,17 @@ } }, "response": { - "$ref": "Human" + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.humans.destroy", - "path": "humans/{uuid}", + "id": "arvados.keep_services.destroy", + "path": "keep_services/{uuid}", "httpMethod": "DELETE", - "description": "destroy humans", + "description": "destroy keep_services", "parameters": { "uuid": { "type": "string", @@ -3271,7 +3284,7 @@ } }, "response": { - "$ref": "Human" + "$ref": "KeepService" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -3279,17 +3292,17 @@ } } }, - "jobs": { + "links": { "methods": { "get": { - "id": "arvados.jobs.get", - "path": "jobs/{uuid}", + "id": "arvados.links.get", + "path": "links/{uuid}", "httpMethod": "GET", - "description": "Gets a Job's metadata by UUID.", + "description": "Gets a Link's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Job in question.", + "description": "The UUID of the Link in question.", "required": true, "location": "path" } @@ -3298,7 +3311,7 @@ "uuid" ], "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3306,10 +3319,10 @@ ] }, "index": { - "id": "arvados.jobs.list", - "path": "jobs", + "id": "arvados.links.list", + "path": "links", "httpMethod": "GET", - "description": "List Jobs.\n\n The list method returns a\n resource list of\n matching Jobs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#jobList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Links.\n\n The list method returns a\n resource list of\n matching Links. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#linkList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -3377,7 +3390,7 @@ } }, "response": { - "$ref": "JobList" + "$ref": "LinkList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3385,10 +3398,10 @@ ] }, "create": { - "id": "arvados.jobs.create", - "path": "jobs", + "id": "arvados.links.create", + "path": "links", "httpMethod": "POST", - "description": "Create a new Job.", + "description": "Create a new Link.", "parameters": { "select": { "type": "array", @@ -3408,57 +3421,32 @@ "description": "Create object on a remote federated cluster instead of the current one.", "location": "query", "required": false - }, - "find_or_create": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "minimum_script_version": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "exclude_script_versions": { - "type": "array", - "required": false, - "description": "", - "location": "query" } }, "request": { "required": true, "properties": { - "job": { - "$ref": "Job" + "link": { + "$ref": "Link" } } }, "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.jobs.update", - "path": "jobs/{uuid}", + "id": "arvados.links.update", + "path": "links/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing Job.", + "description": "Update attributes of an existing Link.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Job in question.", + "description": "The UUID of the Link in question.", "required": true, "location": "path" }, @@ -3472,43 +3460,43 @@ "request": { "required": true, "properties": { - "job": { - "$ref": "Job" + "link": { + "$ref": "Link" } } }, "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.jobs.delete", - "path": "jobs/{uuid}", + "id": "arvados.links.delete", + "path": "links/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing Job.", + "description": "Delete an existing Link.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Job in question.", + "description": "The UUID of the Link in question.", "required": true, "location": "path" } }, "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, - "queue": { - "id": "arvados.jobs.queue", - "path": "jobs/queue", + "list": { + "id": "arvados.links.list", + "path": "links", "httpMethod": "GET", - "description": "queue jobs", + "description": "List Links.\n\n The list method returns a\n resource list of\n matching Links. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#linkList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -3576,175 +3564,64 @@ } }, "response": { - "$ref": "Job" + "$ref": "LinkList" }, "scopes": [ - "https://api.arvados.org/auth/arvados" + "https://api.arvados.org/auth/arvados", + "https://api.arvados.org/auth/arvados.readonly" ] }, - "queue_size": { - "id": "arvados.jobs.queue_size", - "path": "jobs/queue_size", + "show": { + "id": "arvados.links.show", + "path": "links/{uuid}", "httpMethod": "GET", - "description": "queue_size jobs", - "parameters": {}, - "response": { - "$ref": "Job" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "cancel": { - "id": "arvados.jobs.cancel", - "path": "jobs/{uuid}/cancel", - "httpMethod": "POST", - "description": "cancel jobs", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Job" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "lock": { - "id": "arvados.jobs.lock", - "path": "jobs/{uuid}/lock", - "httpMethod": "POST", - "description": "lock jobs", + "description": "show links", "parameters": { "uuid": { "type": "string", "description": "", "required": true, "location": "path" - } - }, - "response": { - "$ref": "Job" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.jobs.list", - "path": "jobs", - "httpMethod": "GET", - "description": "List Jobs.\n\n The list method returns a\n resource list of\n matching Jobs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#jobList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" }, "select": { "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", + "description": "Attributes of the object to return in the response.", "required": false, - "description": "bypass federation behavior, list items from local instance database only", "location": "query" } }, "response": { - "$ref": "JobList" + "$ref": "Link" }, "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" + "https://api.arvados.org/auth/arvados" ] }, - "show": { - "id": "arvados.jobs.show", - "path": "jobs/{uuid}", - "httpMethod": "GET", - "description": "show jobs", + "destroy": { + "id": "arvados.links.destroy", + "path": "links/{uuid}", + "httpMethod": "DELETE", + "description": "destroy links", "parameters": { "uuid": { "type": "string", "description": "", "required": true, "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" } }, "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, - "destroy": { - "id": "arvados.jobs.destroy", - "path": "jobs/{uuid}", - "httpMethod": "DELETE", - "description": "destroy jobs", + "get_permissions": { + "id": "arvados.links.get_permissions", + "path": "permissions/{uuid}", + "httpMethod": "GET", + "description": "get_permissions links", "parameters": { "uuid": { "type": "string", @@ -3754,7 +3631,7 @@ } }, "response": { - "$ref": "Job" + "$ref": "Link" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -3762,17 +3639,17 @@ } } }, - "job_tasks": { + "logs": { "methods": { "get": { - "id": "arvados.job_tasks.get", - "path": "job_tasks/{uuid}", + "id": "arvados.logs.get", + "path": "logs/{uuid}", "httpMethod": "GET", - "description": "Gets a JobTask's metadata by UUID.", + "description": "Gets a Log's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the JobTask in question.", + "description": "The UUID of the Log in question.", "required": true, "location": "path" } @@ -3781,7 +3658,7 @@ "uuid" ], "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3789,10 +3666,10 @@ ] }, "index": { - "id": "arvados.job_tasks.list", - "path": "job_tasks", + "id": "arvados.logs.list", + "path": "logs", "httpMethod": "GET", - "description": "List JobTasks.\n\n The list method returns a\n resource list of\n matching JobTasks. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#jobTaskList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Logs.\n\n The list method returns a\n resource list of\n matching Logs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#logList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -3860,7 +3737,7 @@ } }, "response": { - "$ref": "JobTaskList" + "$ref": "LogList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -3868,10 +3745,10 @@ ] }, "create": { - "id": "arvados.job_tasks.create", - "path": "job_tasks", + "id": "arvados.logs.create", + "path": "logs", "httpMethod": "POST", - "description": "Create a new JobTask.", + "description": "Create a new Log.", "parameters": { "select": { "type": "array", @@ -3896,27 +3773,27 @@ "request": { "required": true, "properties": { - "job_task": { - "$ref": "JobTask" + "log": { + "$ref": "Log" } } }, "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.job_tasks.update", - "path": "job_tasks/{uuid}", + "id": "arvados.logs.update", + "path": "logs/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing JobTask.", + "description": "Update attributes of an existing Log.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the JobTask in question.", + "description": "The UUID of the Log in question.", "required": true, "location": "path" }, @@ -3930,43 +3807,43 @@ "request": { "required": true, "properties": { - "job_task": { - "$ref": "JobTask" - } + "log": { + "$ref": "Log" + } } }, "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.job_tasks.delete", - "path": "job_tasks/{uuid}", + "id": "arvados.logs.delete", + "path": "logs/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing JobTask.", + "description": "Delete an existing Log.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the JobTask in question.", + "description": "The UUID of the Log in question.", "required": true, "location": "path" } }, "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "list": { - "id": "arvados.job_tasks.list", - "path": "job_tasks", + "id": "arvados.logs.list", + "path": "logs", "httpMethod": "GET", - "description": "List JobTasks.\n\n The list method returns a\n resource list of\n matching JobTasks. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#jobTaskList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Logs.\n\n The list method returns a\n resource list of\n matching Logs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#logList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4034,7 +3911,7 @@ } }, "response": { - "$ref": "JobTaskList" + "$ref": "LogList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4042,10 +3919,10 @@ ] }, "show": { - "id": "arvados.job_tasks.show", - "path": "job_tasks/{uuid}", + "id": "arvados.logs.show", + "path": "logs/{uuid}", "httpMethod": "GET", - "description": "show job_tasks", + "description": "show logs", "parameters": { "uuid": { "type": "string", @@ -4061,17 +3938,17 @@ } }, "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.job_tasks.destroy", - "path": "job_tasks/{uuid}", + "id": "arvados.logs.destroy", + "path": "logs/{uuid}", "httpMethod": "DELETE", - "description": "destroy job_tasks", + "description": "destroy logs", "parameters": { "uuid": { "type": "string", @@ -4081,7 +3958,7 @@ } }, "response": { - "$ref": "JobTask" + "$ref": "Log" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -4089,17 +3966,17 @@ } } }, - "keep_disks": { + "users": { "methods": { "get": { - "id": "arvados.keep_disks.get", - "path": "keep_disks/{uuid}", + "id": "arvados.users.get", + "path": "users/{uuid}", "httpMethod": "GET", - "description": "Gets a KeepDisk's metadata by UUID.", + "description": "Gets a User's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepDisk in question.", + "description": "The UUID of the User in question.", "required": true, "location": "path" } @@ -4108,7 +3985,7 @@ "uuid" ], "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4116,10 +3993,10 @@ ] }, "index": { - "id": "arvados.keep_disks.list", - "path": "keep_disks", + "id": "arvados.users.list", + "path": "users", "httpMethod": "GET", - "description": "List KeepDisks.\n\n The list method returns a\n resource list of\n matching KeepDisks. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepDiskList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Users.\n\n The list method returns a\n resource list of\n matching Users. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4187,7 +4064,7 @@ } }, "response": { - "$ref": "KeepDiskList" + "$ref": "UserList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4195,10 +4072,10 @@ ] }, "create": { - "id": "arvados.keep_disks.create", - "path": "keep_disks", + "id": "arvados.users.create", + "path": "users", "httpMethod": "POST", - "description": "Create a new KeepDisk.", + "description": "Create a new User.", "parameters": { "select": { "type": "array", @@ -4223,27 +4100,27 @@ "request": { "required": true, "properties": { - "keep_disk": { - "$ref": "KeepDisk" + "user": { + "$ref": "User" } } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.keep_disks.update", - "path": "keep_disks/{uuid}", + "id": "arvados.users.update", + "path": "users/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing KeepDisk.", + "description": "Update attributes of an existing User.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepDisk in question.", + "description": "The UUID of the User in question.", "required": true, "location": "path" }, @@ -4252,104 +4129,211 @@ "description": "Attributes of the updated object to return in the response.", "required": false, "location": "query" + }, + "bypass_federation": { + "type": "boolean", + "required": false, + "default": "false", + "description": "", + "location": "query" } }, "request": { "required": true, "properties": { - "keep_disk": { - "$ref": "KeepDisk" + "user": { + "$ref": "User" } } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.keep_disks.delete", - "path": "keep_disks/{uuid}", + "id": "arvados.users.delete", + "path": "users/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing KeepDisk.", + "description": "Delete an existing User.", + "parameters": { + "uuid": { + "type": "string", + "description": "The UUID of the User in question.", + "required": true, + "location": "path" + } + }, + "response": { + "$ref": "User" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "current": { + "id": "arvados.users.current", + "path": "users/current", + "httpMethod": "GET", + "description": "current users", + "parameters": {}, + "response": { + "$ref": "User" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "system": { + "id": "arvados.users.system", + "path": "users/system", + "httpMethod": "GET", + "description": "system users", + "parameters": {}, + "response": { + "$ref": "User" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "activate": { + "id": "arvados.users.activate", + "path": "users/{uuid}/activate", + "httpMethod": "POST", + "description": "activate users", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepDisk in question.", + "description": "", "required": true, "location": "path" } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, - "ping": { - "id": "arvados.keep_disks.ping", - "path": "keep_disks/ping", + "setup": { + "id": "arvados.users.setup", + "path": "users/setup", "httpMethod": "POST", - "description": "ping keep_disks", + "description": "setup users", "parameters": { "uuid": { + "type": "string", + "required": false, + "description": "", + "location": "query" + }, + "user": { + "type": "object", "required": false, + "description": "", + "location": "query" + }, + "repo_name": { "type": "string", + "required": false, "description": "", "location": "query" }, - "ping_secret": { - "required": true, + "vm_uuid": { "type": "string", + "required": false, "description": "", "location": "query" }, - "node_uuid": { + "send_notification_email": { + "type": "boolean", "required": false, + "default": "false", + "description": "", + "location": "query" + } + }, + "response": { + "$ref": "User" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "unsetup": { + "id": "arvados.users.unsetup", + "path": "users/{uuid}/unsetup", + "httpMethod": "POST", + "description": "unsetup users", + "parameters": { + "uuid": { + "type": "string", + "description": "", + "required": true, + "location": "path" + } + }, + "response": { + "$ref": "User" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "merge": { + "id": "arvados.users.merge", + "path": "users/merge", + "httpMethod": "POST", + "description": "merge users", + "parameters": { + "new_owner_uuid": { "type": "string", + "required": true, "description": "", "location": "query" }, - "filesystem_uuid": { - "required": false, + "new_user_token": { "type": "string", + "required": false, "description": "", "location": "query" }, - "service_host": { + "redirect_to_new_user": { + "type": "boolean", "required": false, - "type": "string", + "default": "false", "description": "", "location": "query" }, - "service_port": { - "required": true, + "old_user_uuid": { "type": "string", + "required": false, "description": "", "location": "query" }, - "service_ssl_flag": { - "required": true, + "new_user_uuid": { "type": "string", + "required": false, "description": "", "location": "query" } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "list": { - "id": "arvados.keep_disks.list", - "path": "keep_disks", + "id": "arvados.users.list", + "path": "users", "httpMethod": "GET", - "description": "List KeepDisks.\n\n The list method returns a\n resource list of\n matching KeepDisks. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepDiskList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Users.\n\n The list method returns a\n resource list of\n matching Users. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4417,7 +4401,7 @@ } }, "response": { - "$ref": "KeepDiskList" + "$ref": "UserList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4425,10 +4409,10 @@ ] }, "show": { - "id": "arvados.keep_disks.show", - "path": "keep_disks/{uuid}", + "id": "arvados.users.show", + "path": "users/{uuid}", "httpMethod": "GET", - "description": "show keep_disks", + "description": "show users", "parameters": { "uuid": { "type": "string", @@ -4444,17 +4428,17 @@ } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.keep_disks.destroy", - "path": "keep_disks/{uuid}", + "id": "arvados.users.destroy", + "path": "users/{uuid}", "httpMethod": "DELETE", - "description": "destroy keep_disks", + "description": "destroy users", "parameters": { "uuid": { "type": "string", @@ -4464,7 +4448,7 @@ } }, "response": { - "$ref": "KeepDisk" + "$ref": "User" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -4472,17 +4456,17 @@ } } }, - "keep_services": { + "user_agreements": { "methods": { "get": { - "id": "arvados.keep_services.get", - "path": "keep_services/{uuid}", + "id": "arvados.user_agreements.get", + "path": "user_agreements/{uuid}", "httpMethod": "GET", - "description": "Gets a KeepService's metadata by UUID.", + "description": "Gets a UserAgreement's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepService in question.", + "description": "The UUID of the UserAgreement in question.", "required": true, "location": "path" } @@ -4491,7 +4475,7 @@ "uuid" ], "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4499,10 +4483,10 @@ ] }, "index": { - "id": "arvados.keep_services.list", - "path": "keep_services", + "id": "arvados.user_agreements.list", + "path": "user_agreements", "httpMethod": "GET", - "description": "List KeepServices.\n\n The list method returns a\n resource list of\n matching KeepServices. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepServiceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List UserAgreements.\n\n The list method returns a\n resource list of\n matching UserAgreements. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userAgreementList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4570,7 +4554,7 @@ } }, "response": { - "$ref": "KeepServiceList" + "$ref": "UserAgreementList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4578,10 +4562,10 @@ ] }, "create": { - "id": "arvados.keep_services.create", - "path": "keep_services", + "id": "arvados.user_agreements.create", + "path": "user_agreements", "httpMethod": "POST", - "description": "Create a new KeepService.", + "description": "Create a new UserAgreement.", "parameters": { "select": { "type": "array", @@ -4606,27 +4590,27 @@ "request": { "required": true, "properties": { - "keep_service": { - "$ref": "KeepService" + "user_agreement": { + "$ref": "UserAgreement" } } }, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.keep_services.update", - "path": "keep_services/{uuid}", + "id": "arvados.user_agreements.update", + "path": "user_agreements/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing KeepService.", + "description": "Update attributes of an existing UserAgreement.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepService in question.", + "description": "The UUID of the UserAgreement in question.", "required": true, "location": "path" }, @@ -4640,56 +4624,69 @@ "request": { "required": true, "properties": { - "keep_service": { - "$ref": "KeepService" + "user_agreement": { + "$ref": "UserAgreement" } } }, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.keep_services.delete", - "path": "keep_services/{uuid}", + "id": "arvados.user_agreements.delete", + "path": "user_agreements/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing KeepService.", + "description": "Delete an existing UserAgreement.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the KeepService in question.", + "description": "The UUID of the UserAgreement in question.", "required": true, "location": "path" } }, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, - "accessible": { - "id": "arvados.keep_services.accessible", - "path": "keep_services/accessible", + "signatures": { + "id": "arvados.user_agreements.signatures", + "path": "user_agreements/signatures", "httpMethod": "GET", - "description": "accessible keep_services", + "description": "signatures user_agreements", "parameters": {}, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, - "list": { - "id": "arvados.keep_services.list", - "path": "keep_services", + "sign": { + "id": "arvados.user_agreements.sign", + "path": "user_agreements/sign", + "httpMethod": "POST", + "description": "sign user_agreements", + "parameters": {}, + "response": { + "$ref": "UserAgreement" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "list": { + "id": "arvados.user_agreements.list", + "path": "user_agreements", "httpMethod": "GET", - "description": "List KeepServices.\n\n The list method returns a\n resource list of\n matching KeepServices. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#keepServiceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List UserAgreements.\n\n The list method returns a\n resource list of\n matching UserAgreements. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userAgreementList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4757,18 +4754,31 @@ } }, "response": { - "$ref": "KeepServiceList" + "$ref": "UserAgreementList" }, "scopes": [ "https://api.arvados.org/auth/arvados", "https://api.arvados.org/auth/arvados.readonly" ] }, + "new": { + "id": "arvados.user_agreements.new", + "path": "user_agreements/new", + "httpMethod": "GET", + "description": "new user_agreements", + "parameters": {}, + "response": { + "$ref": "UserAgreement" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, "show": { - "id": "arvados.keep_services.show", - "path": "keep_services/{uuid}", + "id": "arvados.user_agreements.show", + "path": "user_agreements/{uuid}", "httpMethod": "GET", - "description": "show keep_services", + "description": "show user_agreements", "parameters": { "uuid": { "type": "string", @@ -4784,17 +4794,17 @@ } }, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.keep_services.destroy", - "path": "keep_services/{uuid}", + "id": "arvados.user_agreements.destroy", + "path": "user_agreements/{uuid}", "httpMethod": "DELETE", - "description": "destroy keep_services", + "description": "destroy user_agreements", "parameters": { "uuid": { "type": "string", @@ -4804,7 +4814,7 @@ } }, "response": { - "$ref": "KeepService" + "$ref": "UserAgreement" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -4812,17 +4822,17 @@ } } }, - "links": { + "virtual_machines": { "methods": { "get": { - "id": "arvados.links.get", - "path": "links/{uuid}", + "id": "arvados.virtual_machines.get", + "path": "virtual_machines/{uuid}", "httpMethod": "GET", - "description": "Gets a Link's metadata by UUID.", + "description": "Gets a VirtualMachine's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Link in question.", + "description": "The UUID of the VirtualMachine in question.", "required": true, "location": "path" } @@ -4831,7 +4841,7 @@ "uuid" ], "response": { - "$ref": "Link" + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4839,10 +4849,10 @@ ] }, "index": { - "id": "arvados.links.list", - "path": "links", + "id": "arvados.virtual_machines.list", + "path": "virtual_machines", "httpMethod": "GET", - "description": "List Links.\n\n The list method returns a\n resource list of\n matching Links. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#linkList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List VirtualMachines.\n\n The list method returns a\n resource list of\n matching VirtualMachines. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#virtualMachineList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -4910,7 +4920,7 @@ } }, "response": { - "$ref": "LinkList" + "$ref": "VirtualMachineList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -4918,10 +4928,10 @@ ] }, "create": { - "id": "arvados.links.create", - "path": "links", + "id": "arvados.virtual_machines.create", + "path": "virtual_machines", "httpMethod": "POST", - "description": "Create a new Link.", + "description": "Create a new VirtualMachine.", "parameters": { "select": { "type": "array", @@ -4946,27 +4956,27 @@ "request": { "required": true, "properties": { - "link": { - "$ref": "Link" + "virtual_machine": { + "$ref": "VirtualMachine" } } }, "response": { - "$ref": "Link" + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.links.update", - "path": "links/{uuid}", + "id": "arvados.virtual_machines.update", + "path": "virtual_machines/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing Link.", + "description": "Update attributes of an existing VirtualMachine.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Link in question.", + "description": "The UUID of the VirtualMachine in question.", "required": true, "location": "path" }, @@ -4980,43 +4990,76 @@ "request": { "required": true, "properties": { - "link": { - "$ref": "Link" + "virtual_machine": { + "$ref": "VirtualMachine" } } }, "response": { - "$ref": "Link" + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.links.delete", - "path": "links/{uuid}", + "id": "arvados.virtual_machines.delete", + "path": "virtual_machines/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing Link.", + "description": "Delete an existing VirtualMachine.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Link in question.", + "description": "The UUID of the VirtualMachine in question.", "required": true, "location": "path" } }, "response": { - "$ref": "Link" + "$ref": "VirtualMachine" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "logins": { + "id": "arvados.virtual_machines.logins", + "path": "virtual_machines/{uuid}/logins", + "httpMethod": "GET", + "description": "logins virtual_machines", + "parameters": { + "uuid": { + "type": "string", + "description": "", + "required": true, + "location": "path" + } + }, + "response": { + "$ref": "VirtualMachine" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] + }, + "get_all_logins": { + "id": "arvados.virtual_machines.get_all_logins", + "path": "virtual_machines/get_all_logins", + "httpMethod": "GET", + "description": "get_all_logins virtual_machines", + "parameters": {}, + "response": { + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "list": { - "id": "arvados.links.list", - "path": "links", + "id": "arvados.virtual_machines.list", + "path": "virtual_machines", "httpMethod": "GET", - "description": "List Links.\n\n The list method returns a\n resource list of\n matching Links. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#linkList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List VirtualMachines.\n\n The list method returns a\n resource list of\n matching VirtualMachines. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#virtualMachineList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -5084,7 +5127,7 @@ } }, "response": { - "$ref": "LinkList" + "$ref": "VirtualMachineList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -5092,10 +5135,10 @@ ] }, "show": { - "id": "arvados.links.show", - "path": "links/{uuid}", + "id": "arvados.virtual_machines.show", + "path": "virtual_machines/{uuid}", "httpMethod": "GET", - "description": "show links", + "description": "show virtual_machines", "parameters": { "uuid": { "type": "string", @@ -5111,37 +5154,17 @@ } }, "response": { - "$ref": "Link" + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.links.destroy", - "path": "links/{uuid}", + "id": "arvados.virtual_machines.destroy", + "path": "virtual_machines/{uuid}", "httpMethod": "DELETE", - "description": "destroy links", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Link" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "get_permissions": { - "id": "arvados.links.get_permissions", - "path": "permissions/{uuid}", - "httpMethod": "GET", - "description": "get_permissions links", + "description": "destroy virtual_machines", "parameters": { "uuid": { "type": "string", @@ -5151,7 +5174,7 @@ } }, "response": { - "$ref": "Link" + "$ref": "VirtualMachine" }, "scopes": [ "https://api.arvados.org/auth/arvados" @@ -5159,17 +5182,17 @@ } } }, - "logs": { + "workflows": { "methods": { "get": { - "id": "arvados.logs.get", - "path": "logs/{uuid}", + "id": "arvados.workflows.get", + "path": "workflows/{uuid}", "httpMethod": "GET", - "description": "Gets a Log's metadata by UUID.", + "description": "Gets a Workflow's metadata by UUID.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Log in question.", + "description": "The UUID of the Workflow in question.", "required": true, "location": "path" } @@ -5178,7 +5201,7 @@ "uuid" ], "response": { - "$ref": "Log" + "$ref": "Workflow" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -5186,10 +5209,10 @@ ] }, "index": { - "id": "arvados.logs.list", - "path": "logs", + "id": "arvados.workflows.list", + "path": "workflows", "httpMethod": "GET", - "description": "List Logs.\n\n The list method returns a\n resource list of\n matching Logs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#logList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Workflows.\n\n The list method returns a\n resource list of\n matching Workflows. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#workflowList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -5257,7 +5280,7 @@ } }, "response": { - "$ref": "LogList" + "$ref": "WorkflowList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -5265,10 +5288,10 @@ ] }, "create": { - "id": "arvados.logs.create", - "path": "logs", + "id": "arvados.workflows.create", + "path": "workflows", "httpMethod": "POST", - "description": "Create a new Log.", + "description": "Create a new Workflow.", "parameters": { "select": { "type": "array", @@ -5293,27 +5316,27 @@ "request": { "required": true, "properties": { - "log": { - "$ref": "Log" + "workflow": { + "$ref": "Workflow" } } }, "response": { - "$ref": "Log" + "$ref": "Workflow" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "update": { - "id": "arvados.logs.update", - "path": "logs/{uuid}", + "id": "arvados.workflows.update", + "path": "workflows/{uuid}", "httpMethod": "PUT", - "description": "Update attributes of an existing Log.", + "description": "Update attributes of an existing Workflow.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Log in question.", + "description": "The UUID of the Workflow in question.", "required": true, "location": "path" }, @@ -5327,43 +5350,43 @@ "request": { "required": true, "properties": { - "log": { - "$ref": "Log" + "workflow": { + "$ref": "Workflow" } } }, "response": { - "$ref": "Log" + "$ref": "Workflow" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "delete": { - "id": "arvados.logs.delete", - "path": "logs/{uuid}", + "id": "arvados.workflows.delete", + "path": "workflows/{uuid}", "httpMethod": "DELETE", - "description": "Delete an existing Log.", + "description": "Delete an existing Workflow.", "parameters": { "uuid": { "type": "string", - "description": "The UUID of the Log in question.", + "description": "The UUID of the Workflow in question.", "required": true, "location": "path" } }, "response": { - "$ref": "Log" + "$ref": "Workflow" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "list": { - "id": "arvados.logs.list", - "path": "logs", + "id": "arvados.workflows.list", + "path": "workflows", "httpMethod": "GET", - "description": "List Logs.\n\n The list method returns a\n resource list of\n matching Logs. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#logList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", + "description": "List Workflows.\n\n The list method returns a\n resource list of\n matching Workflows. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#workflowList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", "parameters": { "filters": { "type": "array", @@ -5431,7 +5454,7 @@ } }, "response": { - "$ref": "LogList" + "$ref": "WorkflowList" }, "scopes": [ "https://api.arvados.org/auth/arvados", @@ -5439,10 +5462,10 @@ ] }, "show": { - "id": "arvados.logs.show", - "path": "logs/{uuid}", + "id": "arvados.workflows.show", + "path": "workflows/{uuid}", "httpMethod": "GET", - "description": "show logs", + "description": "show workflows", "parameters": { "uuid": { "type": "string", @@ -5458,4481 +5481,97 @@ } }, "response": { - "$ref": "Log" + "$ref": "Workflow" }, "scopes": [ "https://api.arvados.org/auth/arvados" ] }, "destroy": { - "id": "arvados.logs.destroy", - "path": "logs/{uuid}", - "httpMethod": "DELETE", - "description": "destroy logs", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Log" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "nodes": { - "methods": { - "get": { - "id": "arvados.nodes.get", - "path": "nodes/{uuid}", - "httpMethod": "GET", - "description": "Gets a Node's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Node in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.nodes.list", - "path": "nodes", - "httpMethod": "GET", - "description": "List Nodes.\n\n The list method returns a\n resource list of\n matching Nodes. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#nodeList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "NodeList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.nodes.create", - "path": "nodes", - "httpMethod": "POST", - "description": "Create a new Node.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "assign_slot": { - "required": false, - "type": "boolean", - "description": "assign slot and hostname", - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "node": { - "$ref": "Node" - } - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.nodes.update", - "path": "nodes/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing Node.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Node in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - }, - "assign_slot": { - "required": false, - "type": "boolean", - "description": "assign slot and hostname", - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "node": { - "$ref": "Node" - } - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.nodes.delete", - "path": "nodes/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing Node.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Node in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "ping": { - "id": "arvados.nodes.ping", - "path": "nodes/{uuid}/ping", - "httpMethod": "POST", - "description": "ping nodes", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "ping_secret": { - "required": true, - "type": "string", - "description": "", - "location": "query" - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.nodes.list", - "path": "nodes", - "httpMethod": "GET", - "description": "List Nodes.\n\n The list method returns a\n resource list of\n matching Nodes. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#nodeList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "NodeList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.nodes.show", - "path": "nodes/{uuid}", - "httpMethod": "GET", - "description": "show nodes", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.nodes.destroy", - "path": "nodes/{uuid}", - "httpMethod": "DELETE", - "description": "destroy nodes", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Node" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "pipeline_instances": { - "methods": { - "get": { - "id": "arvados.pipeline_instances.get", - "path": "pipeline_instances/{uuid}", - "httpMethod": "GET", - "description": "Gets a PipelineInstance's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineInstance in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.pipeline_instances.list", - "path": "pipeline_instances", - "httpMethod": "GET", - "description": "List PipelineInstances.\n\n The list method returns a\n resource list of\n matching PipelineInstances. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#pipelineInstanceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "PipelineInstanceList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.pipeline_instances.create", - "path": "pipeline_instances", - "httpMethod": "POST", - "description": "Create a new PipelineInstance.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "pipeline_instance": { - "$ref": "PipelineInstance" - } - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.pipeline_instances.update", - "path": "pipeline_instances/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing PipelineInstance.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineInstance in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "pipeline_instance": { - "$ref": "PipelineInstance" - } - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.pipeline_instances.delete", - "path": "pipeline_instances/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing PipelineInstance.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineInstance in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "cancel": { - "id": "arvados.pipeline_instances.cancel", - "path": "pipeline_instances/{uuid}/cancel", - "httpMethod": "POST", - "description": "cancel pipeline_instances", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.pipeline_instances.list", - "path": "pipeline_instances", - "httpMethod": "GET", - "description": "List PipelineInstances.\n\n The list method returns a\n resource list of\n matching PipelineInstances. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#pipelineInstanceList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "PipelineInstanceList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.pipeline_instances.show", - "path": "pipeline_instances/{uuid}", - "httpMethod": "GET", - "description": "show pipeline_instances", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.pipeline_instances.destroy", - "path": "pipeline_instances/{uuid}", - "httpMethod": "DELETE", - "description": "destroy pipeline_instances", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "PipelineInstance" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "pipeline_templates": { - "methods": { - "get": { - "id": "arvados.pipeline_templates.get", - "path": "pipeline_templates/{uuid}", - "httpMethod": "GET", - "description": "Gets a PipelineTemplate's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineTemplate in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.pipeline_templates.list", - "path": "pipeline_templates", - "httpMethod": "GET", - "description": "List PipelineTemplates.\n\n The list method returns a\n resource list of\n matching PipelineTemplates. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#pipelineTemplateList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "PipelineTemplateList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.pipeline_templates.create", - "path": "pipeline_templates", - "httpMethod": "POST", - "description": "Create a new PipelineTemplate.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "pipeline_template": { - "$ref": "PipelineTemplate" - } - } - }, - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.pipeline_templates.update", - "path": "pipeline_templates/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing PipelineTemplate.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineTemplate in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "pipeline_template": { - "$ref": "PipelineTemplate" - } - } - }, - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.pipeline_templates.delete", - "path": "pipeline_templates/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing PipelineTemplate.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the PipelineTemplate in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.pipeline_templates.list", - "path": "pipeline_templates", - "httpMethod": "GET", - "description": "List PipelineTemplates.\n\n The list method returns a\n resource list of\n matching PipelineTemplates. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#pipelineTemplateList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "PipelineTemplateList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.pipeline_templates.show", - "path": "pipeline_templates/{uuid}", - "httpMethod": "GET", - "description": "show pipeline_templates", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.pipeline_templates.destroy", - "path": "pipeline_templates/{uuid}", - "httpMethod": "DELETE", - "description": "destroy pipeline_templates", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "PipelineTemplate" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "repositories": { - "methods": { - "get": { - "id": "arvados.repositories.get", - "path": "repositories/{uuid}", - "httpMethod": "GET", - "description": "Gets a Repository's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Repository in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.repositories.list", - "path": "repositories", - "httpMethod": "GET", - "description": "List Repositories.\n\n The list method returns a\n resource list of\n matching Repositories. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#repositoryList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "RepositoryList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.repositories.create", - "path": "repositories", - "httpMethod": "POST", - "description": "Create a new Repository.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "repository": { - "$ref": "Repository" - } - } - }, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.repositories.update", - "path": "repositories/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing Repository.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Repository in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "repository": { - "$ref": "Repository" - } - } - }, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.repositories.delete", - "path": "repositories/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing Repository.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Repository in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "get_all_permissions": { - "id": "arvados.repositories.get_all_permissions", - "path": "repositories/get_all_permissions", - "httpMethod": "GET", - "description": "get_all_permissions repositories", - "parameters": {}, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.repositories.list", - "path": "repositories", - "httpMethod": "GET", - "description": "List Repositories.\n\n The list method returns a\n resource list of\n matching Repositories. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#repositoryList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "RepositoryList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.repositories.show", - "path": "repositories/{uuid}", - "httpMethod": "GET", - "description": "show repositories", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.repositories.destroy", - "path": "repositories/{uuid}", - "httpMethod": "DELETE", - "description": "destroy repositories", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Repository" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "specimens": { - "methods": { - "get": { - "id": "arvados.specimens.get", - "path": "specimens/{uuid}", - "httpMethod": "GET", - "description": "Gets a Specimen's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Specimen in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.specimens.list", - "path": "specimens", - "httpMethod": "GET", - "description": "List Specimens.\n\n The list method returns a\n resource list of\n matching Specimens. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#specimenList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "SpecimenList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.specimens.create", - "path": "specimens", - "httpMethod": "POST", - "description": "Create a new Specimen.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "specimen": { - "$ref": "Specimen" - } - } - }, - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.specimens.update", - "path": "specimens/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing Specimen.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Specimen in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "specimen": { - "$ref": "Specimen" - } - } - }, - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.specimens.delete", - "path": "specimens/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing Specimen.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Specimen in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.specimens.list", - "path": "specimens", - "httpMethod": "GET", - "description": "List Specimens.\n\n The list method returns a\n resource list of\n matching Specimens. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#specimenList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "SpecimenList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.specimens.show", - "path": "specimens/{uuid}", - "httpMethod": "GET", - "description": "show specimens", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.specimens.destroy", - "path": "specimens/{uuid}", - "httpMethod": "DELETE", - "description": "destroy specimens", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Specimen" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "traits": { - "methods": { - "get": { - "id": "arvados.traits.get", - "path": "traits/{uuid}", - "httpMethod": "GET", - "description": "Gets a Trait's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Trait in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.traits.list", - "path": "traits", - "httpMethod": "GET", - "description": "List Traits.\n\n The list method returns a\n resource list of\n matching Traits. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#traitList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "TraitList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.traits.create", - "path": "traits", - "httpMethod": "POST", - "description": "Create a new Trait.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "trait": { - "$ref": "Trait" - } - } - }, - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.traits.update", - "path": "traits/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing Trait.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Trait in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "trait": { - "$ref": "Trait" - } - } - }, - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.traits.delete", - "path": "traits/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing Trait.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Trait in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.traits.list", - "path": "traits", - "httpMethod": "GET", - "description": "List Traits.\n\n The list method returns a\n resource list of\n matching Traits. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#traitList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "TraitList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.traits.show", - "path": "traits/{uuid}", - "httpMethod": "GET", - "description": "show traits", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.traits.destroy", - "path": "traits/{uuid}", - "httpMethod": "DELETE", - "description": "destroy traits", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Trait" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "users": { - "methods": { - "get": { - "id": "arvados.users.get", - "path": "users/{uuid}", - "httpMethod": "GET", - "description": "Gets a User's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the User in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.users.list", - "path": "users", - "httpMethod": "GET", - "description": "List Users.\n\n The list method returns a\n resource list of\n matching Users. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "UserList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.users.create", - "path": "users", - "httpMethod": "POST", - "description": "Create a new User.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "user": { - "$ref": "User" - } - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.users.update", - "path": "users/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing User.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the User in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "user": { - "$ref": "User" - } - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.users.delete", - "path": "users/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing User.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the User in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "current": { - "id": "arvados.users.current", - "path": "users/current", - "httpMethod": "GET", - "description": "current users", - "parameters": {}, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "system": { - "id": "arvados.users.system", - "path": "users/system", - "httpMethod": "GET", - "description": "system users", - "parameters": {}, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "activate": { - "id": "arvados.users.activate", - "path": "users/{uuid}/activate", - "httpMethod": "POST", - "description": "activate users", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "setup": { - "id": "arvados.users.setup", - "path": "users/setup", - "httpMethod": "POST", - "description": "setup users", - "parameters": { - "uuid": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "user": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "repo_name": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "vm_uuid": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "send_notification_email": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "unsetup": { - "id": "arvados.users.unsetup", - "path": "users/{uuid}/unsetup", - "httpMethod": "POST", - "description": "unsetup users", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "merge": { - "id": "arvados.users.merge", - "path": "users/merge", - "httpMethod": "POST", - "description": "merge users", - "parameters": { - "new_owner_uuid": { - "type": "string", - "required": true, - "description": "", - "location": "query" - }, - "new_user_token": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "redirect_to_new_user": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "old_user_uuid": { - "type": "string", - "required": false, - "description": "", - "location": "query" - }, - "new_user_uuid": { - "type": "string", - "required": false, - "description": "", - "location": "query" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.users.list", - "path": "users", - "httpMethod": "GET", - "description": "List Users.\n\n The list method returns a\n resource list of\n matching Users. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "UserList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.users.show", - "path": "users/{uuid}", - "httpMethod": "GET", - "description": "show users", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.users.destroy", - "path": "users/{uuid}", - "httpMethod": "DELETE", - "description": "destroy users", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "User" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "user_agreements": { - "methods": { - "get": { - "id": "arvados.user_agreements.get", - "path": "user_agreements/{uuid}", - "httpMethod": "GET", - "description": "Gets a UserAgreement's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the UserAgreement in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.user_agreements.list", - "path": "user_agreements", - "httpMethod": "GET", - "description": "List UserAgreements.\n\n The list method returns a\n resource list of\n matching UserAgreements. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userAgreementList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "UserAgreementList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.user_agreements.create", - "path": "user_agreements", - "httpMethod": "POST", - "description": "Create a new UserAgreement.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "user_agreement": { - "$ref": "UserAgreement" - } - } - }, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.user_agreements.update", - "path": "user_agreements/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing UserAgreement.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the UserAgreement in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "user_agreement": { - "$ref": "UserAgreement" - } - } - }, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.user_agreements.delete", - "path": "user_agreements/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing UserAgreement.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the UserAgreement in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "signatures": { - "id": "arvados.user_agreements.signatures", - "path": "user_agreements/signatures", - "httpMethod": "GET", - "description": "signatures user_agreements", - "parameters": {}, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "sign": { - "id": "arvados.user_agreements.sign", - "path": "user_agreements/sign", - "httpMethod": "POST", - "description": "sign user_agreements", - "parameters": {}, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.user_agreements.list", - "path": "user_agreements", - "httpMethod": "GET", - "description": "List UserAgreements.\n\n The list method returns a\n resource list of\n matching UserAgreements. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#userAgreementList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "UserAgreementList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "new": { - "id": "arvados.user_agreements.new", - "path": "user_agreements/new", - "httpMethod": "GET", - "description": "new user_agreements", - "parameters": {}, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "show": { - "id": "arvados.user_agreements.show", - "path": "user_agreements/{uuid}", - "httpMethod": "GET", - "description": "show user_agreements", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.user_agreements.destroy", - "path": "user_agreements/{uuid}", - "httpMethod": "DELETE", - "description": "destroy user_agreements", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "UserAgreement" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "virtual_machines": { - "methods": { - "get": { - "id": "arvados.virtual_machines.get", - "path": "virtual_machines/{uuid}", - "httpMethod": "GET", - "description": "Gets a VirtualMachine's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the VirtualMachine in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.virtual_machines.list", - "path": "virtual_machines", - "httpMethod": "GET", - "description": "List VirtualMachines.\n\n The list method returns a\n resource list of\n matching VirtualMachines. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#virtualMachineList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "VirtualMachineList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.virtual_machines.create", - "path": "virtual_machines", - "httpMethod": "POST", - "description": "Create a new VirtualMachine.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "virtual_machine": { - "$ref": "VirtualMachine" - } - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.virtual_machines.update", - "path": "virtual_machines/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing VirtualMachine.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the VirtualMachine in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "virtual_machine": { - "$ref": "VirtualMachine" - } - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.virtual_machines.delete", - "path": "virtual_machines/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing VirtualMachine.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the VirtualMachine in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "logins": { - "id": "arvados.virtual_machines.logins", - "path": "virtual_machines/{uuid}/logins", - "httpMethod": "GET", - "description": "logins virtual_machines", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "get_all_logins": { - "id": "arvados.virtual_machines.get_all_logins", - "path": "virtual_machines/get_all_logins", - "httpMethod": "GET", - "description": "get_all_logins virtual_machines", - "parameters": {}, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.virtual_machines.list", - "path": "virtual_machines", - "httpMethod": "GET", - "description": "List VirtualMachines.\n\n The list method returns a\n resource list of\n matching VirtualMachines. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#virtualMachineList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "VirtualMachineList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.virtual_machines.show", - "path": "virtual_machines/{uuid}", - "httpMethod": "GET", - "description": "show virtual_machines", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.virtual_machines.destroy", - "path": "virtual_machines/{uuid}", - "httpMethod": "DELETE", - "description": "destroy virtual_machines", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "VirtualMachine" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "workflows": { - "methods": { - "get": { - "id": "arvados.workflows.get", - "path": "workflows/{uuid}", - "httpMethod": "GET", - "description": "Gets a Workflow's metadata by UUID.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Workflow in question.", - "required": true, - "location": "path" - } - }, - "parameterOrder": [ - "uuid" - ], - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "index": { - "id": "arvados.workflows.list", - "path": "workflows", - "httpMethod": "GET", - "description": "List Workflows.\n\n The list method returns a\n resource list of\n matching Workflows. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#workflowList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "WorkflowList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "create": { - "id": "arvados.workflows.create", - "path": "workflows", - "httpMethod": "POST", - "description": "Create a new Workflow.", - "parameters": { - "select": { - "type": "array", - "description": "Attributes of the new object to return in the response.", - "required": false, - "location": "query" - }, - "ensure_unique_name": { - "type": "boolean", - "description": "Adjust name to ensure uniqueness instead of returning an error on (owner_uuid, name) collision.", - "location": "query", - "required": false, - "default": "false" - }, - "cluster_id": { - "type": "string", - "description": "Create object on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - } - }, - "request": { - "required": true, - "properties": { - "workflow": { - "$ref": "Workflow" - } - } - }, - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "update": { - "id": "arvados.workflows.update", - "path": "workflows/{uuid}", - "httpMethod": "PUT", - "description": "Update attributes of an existing Workflow.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Workflow in question.", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the updated object to return in the response.", - "required": false, - "location": "query" - } - }, - "request": { - "required": true, - "properties": { - "workflow": { - "$ref": "Workflow" - } - } - }, - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "delete": { - "id": "arvados.workflows.delete", - "path": "workflows/{uuid}", - "httpMethod": "DELETE", - "description": "Delete an existing Workflow.", - "parameters": { - "uuid": { - "type": "string", - "description": "The UUID of the Workflow in question.", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "list": { - "id": "arvados.workflows.list", - "path": "workflows", - "httpMethod": "GET", - "description": "List Workflows.\n\n The list method returns a\n resource list of\n matching Workflows. For example:\n\n
\n                   {\n                    \"kind\":\"arvados#workflowList\",\n                    \"etag\":\"\",\n                    \"self_link\":\"\",\n                    \"next_page_token\":\"\",\n                    \"next_link\":\"\",\n                    \"items\":[\n                       ...\n                    ],\n                    \"items_available\":745,\n                    \"_profile\":{\n                     \"request_time\":0.157236317\n                    }\n                    
", - "parameters": { - "filters": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "where": { - "type": "object", - "required": false, - "description": "", - "location": "query" - }, - "order": { - "type": "array", - "required": false, - "description": "", - "location": "query" - }, - "select": { - "type": "array", - "description": "Attributes of each object to return in the response.", - "required": false, - "location": "query" - }, - "distinct": { - "type": "boolean", - "required": false, - "default": "false", - "description": "", - "location": "query" - }, - "limit": { - "type": "integer", - "required": false, - "default": "100", - "description": "", - "location": "query" - }, - "offset": { - "type": "integer", - "required": false, - "default": "0", - "description": "", - "location": "query" - }, - "count": { - "type": "string", - "required": false, - "default": "exact", - "description": "", - "location": "query" - }, - "cluster_id": { - "type": "string", - "description": "List objects on a remote federated cluster instead of the current one.", - "location": "query", - "required": false - }, - "bypass_federation": { - "type": "boolean", - "required": false, - "description": "bypass federation behavior, list items from local instance database only", - "location": "query" - } - }, - "response": { - "$ref": "WorkflowList" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - }, - "show": { - "id": "arvados.workflows.show", - "path": "workflows/{uuid}", - "httpMethod": "GET", - "description": "show workflows", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - }, - "select": { - "type": "array", - "description": "Attributes of the object to return in the response.", - "required": false, - "location": "query" - } - }, - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - }, - "destroy": { - "id": "arvados.workflows.destroy", - "path": "workflows/{uuid}", - "httpMethod": "DELETE", - "description": "destroy workflows", - "parameters": { - "uuid": { - "type": "string", - "description": "", - "required": true, - "location": "path" - } - }, - "response": { - "$ref": "Workflow" - }, - "scopes": [ - "https://api.arvados.org/auth/arvados" - ] - } - } - }, - "configs": { - "methods": { - "get": { - "id": "arvados.configs.get", - "path": "config", - "httpMethod": "GET", - "description": "Get public config", - "parameters": {}, - "parameterOrder": [], - "response": {}, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - } - } - }, - "vocabularies": { - "methods": { - "get": { - "id": "arvados.vocabularies.get", - "path": "vocabulary", - "httpMethod": "GET", - "description": "Get vocabulary definition", - "parameters": {}, - "parameterOrder": [], - "response": {}, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - } - } - }, - "sys": { - "methods": { - "get": { - "id": "arvados.sys.trash_sweep", - "path": "sys/trash_sweep", - "httpMethod": "POST", - "description": "apply scheduled trash and delete operations", - "parameters": {}, - "parameterOrder": [], - "response": {}, - "scopes": [ - "https://api.arvados.org/auth/arvados", - "https://api.arvados.org/auth/arvados.readonly" - ] - } - } - } - }, - "revision": "20231117", - "schemas": { - "ApiClientList": { - "id": "ApiClientList", - "description": "ApiClient list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#apiClientList.", - "default": "arvados#apiClientList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of ApiClients.", - "items": { - "$ref": "ApiClient" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of ApiClients." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of ApiClients." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "ApiClient": { - "id": "ApiClient", - "description": "ApiClient", - "type": "object", - "uuidPrefix": "ozdt8", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "name": { - "type": "string" - }, - "url_prefix": { - "type": "string" - }, - "created_at": { - "type": "datetime" - }, - "is_trusted": { - "type": "boolean" - } - } - }, - "ApiClientAuthorizationList": { - "id": "ApiClientAuthorizationList", - "description": "ApiClientAuthorization list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#apiClientAuthorizationList.", - "default": "arvados#apiClientAuthorizationList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of ApiClientAuthorizations.", - "items": { - "$ref": "ApiClientAuthorization" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of ApiClientAuthorizations." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of ApiClientAuthorizations." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "ApiClientAuthorization": { - "id": "ApiClientAuthorization", - "description": "ApiClientAuthorization", - "type": "object", - "uuidPrefix": "gj3su", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "api_token": { - "type": "string" - }, - "api_client_id": { - "type": "integer" - }, - "user_id": { - "type": "integer" - }, - "created_by_ip_address": { - "type": "string" - }, - "last_used_by_ip_address": { - "type": "string" - }, - "last_used_at": { - "type": "datetime" - }, - "expires_at": { - "type": "datetime" - }, - "created_at": { - "type": "datetime" - }, - "default_owner_uuid": { - "type": "string" - }, - "scopes": { - "type": "Array" - } - } - }, - "AuthorizedKeyList": { - "id": "AuthorizedKeyList", - "description": "AuthorizedKey list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#authorizedKeyList.", - "default": "arvados#authorizedKeyList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of AuthorizedKeys.", - "items": { - "$ref": "AuthorizedKey" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of AuthorizedKeys." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of AuthorizedKeys." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "AuthorizedKey": { - "id": "AuthorizedKey", - "description": "AuthorizedKey", - "type": "object", - "uuidPrefix": "fngyi", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "name": { - "type": "string" - }, - "key_type": { - "type": "string" - }, - "authorized_user_uuid": { - "type": "string" - }, - "public_key": { - "type": "text" - }, - "expires_at": { - "type": "datetime" - }, - "created_at": { - "type": "datetime" - } - } - }, - "CollectionList": { - "id": "CollectionList", - "description": "Collection list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#collectionList.", - "default": "arvados#collectionList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of Collections.", - "items": { - "$ref": "Collection" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of Collections." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of Collections." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "Collection": { - "id": "Collection", - "description": "Collection", - "type": "object", - "uuidPrefix": "4zz18", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "created_at": { - "type": "datetime" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "portable_data_hash": { - "type": "string" - }, - "replication_desired": { - "type": "integer" - }, - "replication_confirmed_at": { - "type": "datetime" - }, - "replication_confirmed": { - "type": "integer" - }, - "manifest_text": { - "type": "text" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "properties": { - "type": "Hash" - }, - "delete_at": { - "type": "datetime" - }, - "trash_at": { - "type": "datetime" - }, - "is_trashed": { - "type": "boolean" - }, - "storage_classes_desired": { - "type": "Array" - }, - "storage_classes_confirmed": { - "type": "Array" - }, - "storage_classes_confirmed_at": { - "type": "datetime" - }, - "current_version_uuid": { - "type": "string" - }, - "version": { - "type": "integer" - }, - "preserve_version": { - "type": "boolean" - }, - "file_count": { - "type": "integer" - }, - "file_size_total": { - "type": "integer" - } - } - }, - "ContainerList": { - "id": "ContainerList", - "description": "Container list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#containerList.", - "default": "arvados#containerList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of Containers.", - "items": { - "$ref": "Container" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of Containers." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of Containers." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "Container": { - "id": "Container", - "description": "Container", - "type": "object", - "uuidPrefix": "dz642", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "created_at": { - "type": "datetime" - }, - "modified_at": { - "type": "datetime" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "state": { - "type": "string" - }, - "started_at": { - "type": "datetime" - }, - "finished_at": { - "type": "datetime" - }, - "log": { - "type": "string" - }, - "environment": { - "type": "Hash" - }, - "cwd": { - "type": "string" - }, - "command": { - "type": "Array" - }, - "output_path": { - "type": "string" - }, - "mounts": { - "type": "Hash" - }, - "runtime_constraints": { - "type": "Hash" - }, - "output": { - "type": "string" - }, - "container_image": { - "type": "string" - }, - "progress": { - "type": "float" - }, - "priority": { - "type": "integer" - }, - "exit_code": { - "type": "integer" - }, - "auth_uuid": { - "type": "string" - }, - "locked_by_uuid": { - "type": "string" - }, - "scheduling_parameters": { - "type": "Hash" - }, - "runtime_status": { - "type": "Hash" - }, - "runtime_user_uuid": { - "type": "text" - }, - "runtime_auth_scopes": { - "type": "Array" - }, - "lock_count": { - "type": "integer" - }, - "gateway_address": { - "type": "string" - }, - "interactive_session_started": { - "type": "boolean" - }, - "output_storage_classes": { - "type": "Array" - }, - "output_properties": { - "type": "Hash" - }, - "cost": { - "type": "float" - }, - "subrequests_cost": { - "type": "float" - } - } - }, - "ContainerRequestList": { - "id": "ContainerRequestList", - "description": "ContainerRequest list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#containerRequestList.", - "default": "arvados#containerRequestList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of ContainerRequests.", - "items": { - "$ref": "ContainerRequest" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of ContainerRequests." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of ContainerRequests." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "ContainerRequest": { - "id": "ContainerRequest", - "description": "ContainerRequest", - "type": "object", - "uuidPrefix": "xvhdp", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "created_at": { - "type": "datetime" - }, - "modified_at": { - "type": "datetime" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "name": { - "type": "string" - }, - "description": { - "type": "text" - }, - "properties": { - "type": "Hash" - }, - "state": { - "type": "string" - }, - "requesting_container_uuid": { - "type": "string" - }, - "container_uuid": { - "type": "string" - }, - "container_count_max": { - "type": "integer" - }, - "mounts": { - "type": "Hash" - }, - "runtime_constraints": { - "type": "Hash" - }, - "container_image": { - "type": "string" - }, - "environment": { - "type": "Hash" - }, - "cwd": { - "type": "string" - }, - "command": { - "type": "Array" - }, - "output_path": { - "type": "string" - }, - "priority": { - "type": "integer" - }, - "expires_at": { - "type": "datetime" - }, - "filters": { - "type": "text" - }, - "container_count": { - "type": "integer" - }, - "use_existing": { - "type": "boolean" - }, - "scheduling_parameters": { - "type": "Hash" - }, - "output_uuid": { - "type": "string" - }, - "log_uuid": { - "type": "string" - }, - "output_name": { - "type": "string" - }, - "output_ttl": { - "type": "integer" - }, - "output_storage_classes": { - "type": "Array" - }, - "output_properties": { - "type": "Hash" - }, - "cumulative_cost": { - "type": "float" - } - } - }, - "GroupList": { - "id": "GroupList", - "description": "Group list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#groupList.", - "default": "arvados#groupList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of Groups.", - "items": { - "$ref": "Group" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of Groups." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of Groups." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "Group": { - "id": "Group", - "description": "Group", - "type": "object", - "uuidPrefix": "j7d0g", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "created_at": { - "type": "datetime" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "name": { - "type": "string" - }, - "description": { - "type": "string" - }, - "group_class": { - "type": "string" - }, - "trash_at": { - "type": "datetime" - }, - "is_trashed": { - "type": "boolean" - }, - "delete_at": { - "type": "datetime" - }, - "properties": { - "type": "Hash" - }, - "frozen_by_uuid": { - "type": "string" + "id": "arvados.workflows.destroy", + "path": "workflows/{uuid}", + "httpMethod": "DELETE", + "description": "destroy workflows", + "parameters": { + "uuid": { + "type": "string", + "description": "", + "required": true, + "location": "path" + } + }, + "response": { + "$ref": "Workflow" + }, + "scopes": [ + "https://api.arvados.org/auth/arvados" + ] } } }, - "HumanList": { - "id": "HumanList", - "description": "Human list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#humanList.", - "default": "arvados#humanList" - }, - "etag": { - "type": "string", - "description": "List version." - }, - "items": { - "type": "array", - "description": "The list of Humans.", - "items": { - "$ref": "Human" - } - }, - "next_link": { - "type": "string", - "description": "A link to the next page of Humans." - }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of Humans." - }, - "selfLink": { - "type": "string", - "description": "A link back to this list." + "configs": { + "methods": { + "get": { + "id": "arvados.configs.get", + "path": "config", + "httpMethod": "GET", + "description": "Get public config", + "parameters": {}, + "parameterOrder": [], + "response": {}, + "scopes": [ + "https://api.arvados.org/auth/arvados", + "https://api.arvados.org/auth/arvados.readonly" + ] } } }, - "Human": { - "id": "Human", - "description": "Human", - "type": "object", - "uuidPrefix": "7a9it", - "properties": { - "uuid": { - "type": "string" - }, - "etag": { - "type": "string", - "description": "Object version." - }, - "owner_uuid": { - "type": "string" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "properties": { - "type": "Hash" - }, - "created_at": { - "type": "datetime" + "vocabularies": { + "methods": { + "get": { + "id": "arvados.vocabularies.get", + "path": "vocabulary", + "httpMethod": "GET", + "description": "Get vocabulary definition", + "parameters": {}, + "parameterOrder": [], + "response": {}, + "scopes": [ + "https://api.arvados.org/auth/arvados", + "https://api.arvados.org/auth/arvados.readonly" + ] } } }, - "JobList": { - "id": "JobList", - "description": "Job list", + "sys": { + "methods": { + "get": { + "id": "arvados.sys.trash_sweep", + "path": "sys/trash_sweep", + "httpMethod": "POST", + "description": "apply scheduled trash and delete operations", + "parameters": {}, + "parameterOrder": [], + "response": {}, + "scopes": [ + "https://api.arvados.org/auth/arvados", + "https://api.arvados.org/auth/arvados.readonly" + ] + } + } + } + }, + "revision": "20231117", + "schemas": { + "ApiClientList": { + "id": "ApiClientList", + "description": "ApiClient list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#jobList.", - "default": "arvados#jobList" + "description": "Object type. Always arvados#apiClientList.", + "default": "arvados#apiClientList" }, "etag": { "type": "string", @@ -9940,18 +5579,18 @@ }, "items": { "type": "array", - "description": "The list of Jobs.", + "description": "The list of ApiClients.", "items": { - "$ref": "Job" + "$ref": "ApiClient" } }, "next_link": { "type": "string", - "description": "A link to the next page of Jobs." + "description": "A link to the next page of ApiClients." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Jobs." + "description": "The page token for the next page of ApiClients." }, "selfLink": { "type": "string", @@ -9959,11 +5598,11 @@ } } }, - "Job": { - "id": "Job", - "description": "Job", + "ApiClient": { + "id": "ApiClient", + "description": "ApiClient", "type": "object", - "uuidPrefix": "8i9sb", + "uuidPrefix": "ozdt8", "properties": { "uuid": { "type": "string" @@ -9984,95 +5623,29 @@ "modified_at": { "type": "datetime" }, - "submit_id": { - "type": "string" - }, - "script": { - "type": "string" - }, - "script_version": { - "type": "string" - }, - "script_parameters": { - "type": "Hash" - }, - "cancelled_by_client_uuid": { - "type": "string" - }, - "cancelled_by_user_uuid": { + "name": { "type": "string" }, - "cancelled_at": { - "type": "datetime" - }, - "started_at": { - "type": "datetime" - }, - "finished_at": { - "type": "datetime" - }, - "running": { - "type": "boolean" - }, - "success": { - "type": "boolean" - }, - "output": { + "url_prefix": { "type": "string" }, "created_at": { "type": "datetime" }, - "is_locked_by_uuid": { - "type": "string" - }, - "log": { - "type": "string" - }, - "tasks_summary": { - "type": "Hash" - }, - "runtime_constraints": { - "type": "Hash" - }, - "nondeterministic": { + "is_trusted": { "type": "boolean" - }, - "repository": { - "type": "string" - }, - "supplied_script_version": { - "type": "string" - }, - "docker_image_locator": { - "type": "string" - }, - "priority": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "state": { - "type": "string" - }, - "arvados_sdk_version": { - "type": "string" - }, - "components": { - "type": "Hash" } } }, - "JobTaskList": { - "id": "JobTaskList", - "description": "JobTask list", + "ApiClientAuthorizationList": { + "id": "ApiClientAuthorizationList", + "description": "ApiClientAuthorization list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#jobTaskList.", - "default": "arvados#jobTaskList" + "description": "Object type. Always arvados#apiClientAuthorizationList.", + "default": "arvados#apiClientAuthorizationList" }, "etag": { "type": "string", @@ -10080,18 +5653,18 @@ }, "items": { "type": "array", - "description": "The list of JobTasks.", + "description": "The list of ApiClientAuthorizations.", "items": { - "$ref": "JobTask" + "$ref": "ApiClientAuthorization" } }, "next_link": { "type": "string", - "description": "A link to the next page of JobTasks." + "description": "A link to the next page of ApiClientAuthorizations." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of JobTasks." + "description": "The page token for the next page of ApiClientAuthorizations." }, "selfLink": { "type": "string", @@ -10099,11 +5672,11 @@ } } }, - "JobTask": { - "id": "JobTask", - "description": "JobTask", + "ApiClientAuthorization": { + "id": "ApiClientAuthorization", + "description": "ApiClientAuthorization", "type": "object", - "uuidPrefix": "ot0gb", + "uuidPrefix": "gj3su", "properties": { "uuid": { "type": "string" @@ -10112,62 +5685,47 @@ "type": "string", "description": "Object version." }, - "owner_uuid": { - "type": "string" - }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, - "modified_at": { - "type": "datetime" - }, - "job_uuid": { + "api_token": { "type": "string" }, - "sequence": { + "api_client_id": { "type": "integer" }, - "parameters": { - "type": "Hash" - }, - "output": { - "type": "text" - }, - "progress": { - "type": "float" - }, - "success": { - "type": "boolean" + "user_id": { + "type": "integer" }, - "created_at": { - "type": "datetime" + "created_by_ip_address": { + "type": "string" }, - "created_by_job_task_uuid": { + "last_used_by_ip_address": { "type": "string" }, - "qsequence": { - "type": "integer" + "last_used_at": { + "type": "datetime" }, - "started_at": { + "expires_at": { "type": "datetime" }, - "finished_at": { + "created_at": { "type": "datetime" + }, + "default_owner_uuid": { + "type": "string" + }, + "scopes": { + "type": "Array" } } }, - "KeepDiskList": { - "id": "KeepDiskList", - "description": "KeepDisk list", + "AuthorizedKeyList": { + "id": "AuthorizedKeyList", + "description": "AuthorizedKey list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#keepDiskList.", - "default": "arvados#keepDiskList" + "description": "Object type. Always arvados#authorizedKeyList.", + "default": "arvados#authorizedKeyList" }, "etag": { "type": "string", @@ -10175,18 +5733,18 @@ }, "items": { "type": "array", - "description": "The list of KeepDisks.", + "description": "The list of AuthorizedKeys.", "items": { - "$ref": "KeepDisk" + "$ref": "AuthorizedKey" } }, "next_link": { "type": "string", - "description": "A link to the next page of KeepDisks." + "description": "A link to the next page of AuthorizedKeys." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of KeepDisks." + "description": "The page token for the next page of AuthorizedKeys." }, "selfLink": { "type": "string", @@ -10194,11 +5752,11 @@ } } }, - "KeepDisk": { - "id": "KeepDisk", - "description": "KeepDisk", + "AuthorizedKey": { + "id": "AuthorizedKey", + "description": "AuthorizedKey", "type": "object", - "uuidPrefix": "penuu", + "uuidPrefix": "fngyi", "properties": { "uuid": { "type": "string" @@ -10219,50 +5777,35 @@ "modified_at": { "type": "datetime" }, - "node_uuid": { + "name": { "type": "string" }, - "filesystem_uuid": { + "key_type": { "type": "string" }, - "bytes_total": { - "type": "integer" - }, - "bytes_free": { - "type": "integer" - }, - "is_readable": { - "type": "boolean" - }, - "is_writable": { - "type": "boolean" - }, - "last_read_at": { - "type": "datetime" + "authorized_user_uuid": { + "type": "string" }, - "last_write_at": { - "type": "datetime" + "public_key": { + "type": "text" }, - "last_ping_at": { + "expires_at": { "type": "datetime" }, "created_at": { "type": "datetime" - }, - "keep_service_uuid": { - "type": "string" } } }, - "KeepServiceList": { - "id": "KeepServiceList", - "description": "KeepService list", + "CollectionList": { + "id": "CollectionList", + "description": "Collection list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#keepServiceList.", - "default": "arvados#keepServiceList" + "description": "Object type. Always arvados#collectionList.", + "default": "arvados#collectionList" }, "etag": { "type": "string", @@ -10270,18 +5813,18 @@ }, "items": { "type": "array", - "description": "The list of KeepServices.", + "description": "The list of Collections.", "items": { - "$ref": "KeepService" + "$ref": "Collection" } }, "next_link": { "type": "string", - "description": "A link to the next page of KeepServices." + "description": "A link to the next page of Collections." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of KeepServices." + "description": "The page token for the next page of Collections." }, "selfLink": { "type": "string", @@ -10289,11 +5832,11 @@ } } }, - "KeepService": { - "id": "KeepService", - "description": "KeepService", + "Collection": { + "id": "Collection", + "description": "Collection", "type": "object", - "uuidPrefix": "bi6l4", + "uuidPrefix": "4zz18", "properties": { "uuid": { "type": "string" @@ -10305,6 +5848,9 @@ "owner_uuid": { "type": "string" }, + "created_at": { + "type": "datetime" + }, "modified_by_client_uuid": { "type": "string" }, @@ -10314,35 +5860,74 @@ "modified_at": { "type": "datetime" }, - "service_host": { + "portable_data_hash": { "type": "string" }, - "service_port": { + "replication_desired": { "type": "integer" }, - "service_ssl_flag": { - "type": "boolean" + "replication_confirmed_at": { + "type": "datetime" }, - "service_type": { + "replication_confirmed": { + "type": "integer" + }, + "manifest_text": { + "type": "text" + }, + "name": { "type": "string" }, - "created_at": { + "description": { + "type": "string" + }, + "properties": { + "type": "Hash" + }, + "delete_at": { "type": "datetime" }, - "read_only": { + "trash_at": { + "type": "datetime" + }, + "is_trashed": { + "type": "boolean" + }, + "storage_classes_desired": { + "type": "Array" + }, + "storage_classes_confirmed": { + "type": "Array" + }, + "storage_classes_confirmed_at": { + "type": "datetime" + }, + "current_version_uuid": { + "type": "string" + }, + "version": { + "type": "integer" + }, + "preserve_version": { "type": "boolean" + }, + "file_count": { + "type": "integer" + }, + "file_size_total": { + "type": "integer" } } }, - "LinkList": { - "id": "LinkList", - "description": "Link list", + "ContainerList": { + "id": "ContainerList", + "description": "Container list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#linkList.", - "default": "arvados#linkList" + "description": "Object type. Always arvados#containerList.", + "default": "arvados#containerList" }, "etag": { "type": "string", @@ -10350,18 +5935,18 @@ }, "items": { "type": "array", - "description": "The list of Links.", + "description": "The list of Containers.", "items": { - "$ref": "Link" + "$ref": "Container" } }, "next_link": { "type": "string", - "description": "A link to the next page of Links." + "description": "A link to the next page of Containers." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Links." + "description": "The page token for the next page of Containers." }, "selfLink": { "type": "string", @@ -10369,11 +5954,11 @@ } } }, - "Link": { - "id": "Link", - "description": "Link", + "Container": { + "id": "Container", + "description": "Container", "type": "object", - "uuidPrefix": "o0j2j", + "uuidPrefix": "dz642", "properties": { "uuid": { "type": "string" @@ -10388,127 +5973,113 @@ "created_at": { "type": "datetime" }, + "modified_at": { + "type": "datetime" + }, "modified_by_client_uuid": { "type": "string" }, "modified_by_user_uuid": { "type": "string" }, - "modified_at": { + "state": { + "type": "string" + }, + "started_at": { "type": "datetime" }, - "tail_uuid": { - "type": "string" + "finished_at": { + "type": "datetime" }, - "link_class": { + "log": { "type": "string" }, - "name": { - "type": "string" + "environment": { + "type": "Hash" }, - "head_uuid": { + "cwd": { "type": "string" }, - "properties": { - "type": "Hash" - } - } - }, - "LogList": { - "id": "LogList", - "description": "Log list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#logList.", - "default": "arvados#logList" + "command": { + "type": "Array" }, - "etag": { - "type": "string", - "description": "List version." + "output_path": { + "type": "string" }, - "items": { - "type": "array", - "description": "The list of Logs.", - "items": { - "$ref": "Log" - } + "mounts": { + "type": "Hash" }, - "next_link": { - "type": "string", - "description": "A link to the next page of Logs." + "runtime_constraints": { + "type": "Hash" }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of Logs." + "output": { + "type": "string" }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "Log": { - "id": "Log", - "description": "Log", - "type": "object", - "uuidPrefix": "57u5n", - "properties": { - "uuid": { + "container_image": { "type": "string" }, - "etag": { - "type": "string", - "description": "Object version." + "progress": { + "type": "float" }, - "id": { + "priority": { "type": "integer" }, - "owner_uuid": { - "type": "string" + "exit_code": { + "type": "integer" }, - "modified_by_client_uuid": { + "auth_uuid": { "type": "string" }, - "modified_by_user_uuid": { + "locked_by_uuid": { "type": "string" }, - "object_uuid": { - "type": "string" + "scheduling_parameters": { + "type": "Hash" }, - "event_at": { - "type": "datetime" + "runtime_status": { + "type": "Hash" }, - "event_type": { + "runtime_user_uuid": { + "type": "text" + }, + "runtime_auth_scopes": { + "type": "Array" + }, + "lock_count": { + "type": "integer" + }, + "gateway_address": { "type": "string" }, - "summary": { - "type": "text" + "interactive_session_started": { + "type": "boolean" + }, + "output_storage_classes": { + "type": "Array" }, - "properties": { + "output_properties": { "type": "Hash" }, - "created_at": { - "type": "datetime" + "cost": { + "type": "float" }, - "modified_at": { - "type": "datetime" + "subrequests_cost": { + "type": "float" }, - "object_owner_uuid": { - "type": "string" + "output_glob": { + "type": "Array" } } }, - "NodeList": { - "id": "NodeList", - "description": "Node list", + "ContainerRequestList": { + "id": "ContainerRequestList", + "description": "ContainerRequest list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#nodeList.", - "default": "arvados#nodeList" + "description": "Object type. Always arvados#containerRequestList.", + "default": "arvados#containerRequestList" }, "etag": { "type": "string", @@ -10516,18 +6087,18 @@ }, "items": { "type": "array", - "description": "The list of Nodes.", + "description": "The list of ContainerRequests.", "items": { - "$ref": "Node" + "$ref": "ContainerRequest" } }, "next_link": { "type": "string", - "description": "A link to the next page of Nodes." + "description": "A link to the next page of ContainerRequests." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Nodes." + "description": "The page token for the next page of ContainerRequests." }, "selfLink": { "type": "string", @@ -10535,11 +6106,11 @@ } } }, - "Node": { - "id": "Node", - "description": "Node", + "ContainerRequest": { + "id": "ContainerRequest", + "description": "ContainerRequest", "type": "object", - "uuidPrefix": "7ekkf", + "uuidPrefix": "xvhdp", "properties": { "uuid": { "type": "string" @@ -10554,139 +6125,110 @@ "created_at": { "type": "datetime" }, - "modified_by_client_uuid": { - "type": "string" - }, - "modified_by_user_uuid": { - "type": "string" - }, "modified_at": { "type": "datetime" }, - "slot_number": { - "type": "integer" - }, - "hostname": { + "modified_by_client_uuid": { "type": "string" }, - "domain": { + "modified_by_user_uuid": { "type": "string" }, - "ip_address": { + "name": { "type": "string" }, - "last_ping_at": { - "type": "datetime" + "description": { + "type": "text" }, "properties": { "type": "Hash" }, - "job_uuid": { + "state": { "type": "string" - } - } - }, - "PipelineInstanceList": { - "id": "PipelineInstanceList", - "description": "PipelineInstance list", - "type": "object", - "properties": { - "kind": { - "type": "string", - "description": "Object type. Always arvados#pipelineInstanceList.", - "default": "arvados#pipelineInstanceList" }, - "etag": { - "type": "string", - "description": "List version." + "requesting_container_uuid": { + "type": "string" }, - "items": { - "type": "array", - "description": "The list of PipelineInstances.", - "items": { - "$ref": "PipelineInstance" - } + "container_uuid": { + "type": "string" }, - "next_link": { - "type": "string", - "description": "A link to the next page of PipelineInstances." + "container_count_max": { + "type": "integer" }, - "next_page_token": { - "type": "string", - "description": "The page token for the next page of PipelineInstances." + "mounts": { + "type": "Hash" }, - "selfLink": { - "type": "string", - "description": "A link back to this list." - } - } - }, - "PipelineInstance": { - "id": "PipelineInstance", - "description": "PipelineInstance", - "type": "object", - "uuidPrefix": "d1hrv", - "properties": { - "uuid": { + "runtime_constraints": { + "type": "Hash" + }, + "container_image": { "type": "string" }, - "etag": { - "type": "string", - "description": "Object version." + "environment": { + "type": "Hash" }, - "owner_uuid": { + "cwd": { "type": "string" }, - "created_at": { - "type": "datetime" + "command": { + "type": "Array" }, - "modified_by_client_uuid": { + "output_path": { "type": "string" }, - "modified_by_user_uuid": { - "type": "string" + "priority": { + "type": "integer" }, - "modified_at": { + "expires_at": { "type": "datetime" }, - "pipeline_template_uuid": { - "type": "string" + "filters": { + "type": "text" }, - "name": { - "type": "string" + "container_count": { + "type": "integer" }, - "components": { - "type": "Hash" + "use_existing": { + "type": "boolean" }, - "properties": { + "scheduling_parameters": { "type": "Hash" }, - "state": { + "output_uuid": { "type": "string" }, - "components_summary": { - "type": "Hash" + "log_uuid": { + "type": "string" }, - "started_at": { - "type": "datetime" + "output_name": { + "type": "string" }, - "finished_at": { - "type": "datetime" + "output_ttl": { + "type": "integer" }, - "description": { - "type": "string" + "output_storage_classes": { + "type": "Array" + }, + "output_properties": { + "type": "Hash" + }, + "cumulative_cost": { + "type": "float" + }, + "output_glob": { + "type": "Array" } } }, - "PipelineTemplateList": { - "id": "PipelineTemplateList", - "description": "PipelineTemplate list", + "GroupList": { + "id": "GroupList", + "description": "Group list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#pipelineTemplateList.", - "default": "arvados#pipelineTemplateList" + "description": "Object type. Always arvados#groupList.", + "default": "arvados#groupList" }, "etag": { "type": "string", @@ -10694,18 +6236,18 @@ }, "items": { "type": "array", - "description": "The list of PipelineTemplates.", + "description": "The list of Groups.", "items": { - "$ref": "PipelineTemplate" + "$ref": "Group" } }, "next_link": { "type": "string", - "description": "A link to the next page of PipelineTemplates." + "description": "A link to the next page of Groups." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of PipelineTemplates." + "description": "The page token for the next page of Groups." }, "selfLink": { "type": "string", @@ -10713,11 +6255,11 @@ } } }, - "PipelineTemplate": { - "id": "PipelineTemplate", - "description": "PipelineTemplate", + "Group": { + "id": "Group", + "description": "Group", "type": "object", - "uuidPrefix": "p5p6p", + "uuidPrefix": "j7d0g", "properties": { "uuid": { "type": "string" @@ -10744,23 +6286,38 @@ "name": { "type": "string" }, - "components": { + "description": { + "type": "string" + }, + "group_class": { + "type": "string" + }, + "trash_at": { + "type": "datetime" + }, + "is_trashed": { + "type": "boolean" + }, + "delete_at": { + "type": "datetime" + }, + "properties": { "type": "Hash" }, - "description": { + "frozen_by_uuid": { "type": "string" } } }, - "RepositoryList": { - "id": "RepositoryList", - "description": "Repository list", + "KeepServiceList": { + "id": "KeepServiceList", + "description": "KeepService list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#repositoryList.", - "default": "arvados#repositoryList" + "description": "Object type. Always arvados#keepServiceList.", + "default": "arvados#keepServiceList" }, "etag": { "type": "string", @@ -10768,18 +6325,18 @@ }, "items": { "type": "array", - "description": "The list of Repositories.", + "description": "The list of KeepServices.", "items": { - "$ref": "Repository" + "$ref": "KeepService" } }, "next_link": { "type": "string", - "description": "A link to the next page of Repositories." + "description": "A link to the next page of KeepServices." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Repositories." + "description": "The page token for the next page of KeepServices." }, "selfLink": { "type": "string", @@ -10787,11 +6344,11 @@ } } }, - "Repository": { - "id": "Repository", - "description": "Repository", + "KeepService": { + "id": "KeepService", + "description": "KeepService", "type": "object", - "uuidPrefix": "s0uqq", + "uuidPrefix": "bi6l4", "properties": { "uuid": { "type": "string" @@ -10812,23 +6369,35 @@ "modified_at": { "type": "datetime" }, - "name": { + "service_host": { + "type": "string" + }, + "service_port": { + "type": "integer" + }, + "service_ssl_flag": { + "type": "boolean" + }, + "service_type": { "type": "string" }, "created_at": { "type": "datetime" + }, + "read_only": { + "type": "boolean" } } }, - "SpecimenList": { - "id": "SpecimenList", - "description": "Specimen list", + "LinkList": { + "id": "LinkList", + "description": "Link list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#specimenList.", - "default": "arvados#specimenList" + "description": "Object type. Always arvados#linkList.", + "default": "arvados#linkList" }, "etag": { "type": "string", @@ -10836,18 +6405,18 @@ }, "items": { "type": "array", - "description": "The list of Specimens.", + "description": "The list of Links.", "items": { - "$ref": "Specimen" + "$ref": "Link" } }, "next_link": { "type": "string", - "description": "A link to the next page of Specimens." + "description": "A link to the next page of Links." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Specimens." + "description": "The page token for the next page of Links." }, "selfLink": { "type": "string", @@ -10855,11 +6424,11 @@ } } }, - "Specimen": { - "id": "Specimen", - "description": "Specimen", + "Link": { + "id": "Link", + "description": "Link", "type": "object", - "uuidPrefix": "j58dm", + "uuidPrefix": "o0j2j", "properties": { "uuid": { "type": "string" @@ -10883,7 +6452,16 @@ "modified_at": { "type": "datetime" }, - "material": { + "tail_uuid": { + "type": "string" + }, + "link_class": { + "type": "string" + }, + "name": { + "type": "string" + }, + "head_uuid": { "type": "string" }, "properties": { @@ -10891,15 +6469,15 @@ } } }, - "TraitList": { - "id": "TraitList", - "description": "Trait list", + "LogList": { + "id": "LogList", + "description": "Log list", "type": "object", "properties": { "kind": { "type": "string", - "description": "Object type. Always arvados#traitList.", - "default": "arvados#traitList" + "description": "Object type. Always arvados#logList.", + "default": "arvados#logList" }, "etag": { "type": "string", @@ -10907,18 +6485,18 @@ }, "items": { "type": "array", - "description": "The list of Traits.", + "description": "The list of Logs.", "items": { - "$ref": "Trait" + "$ref": "Log" } }, "next_link": { "type": "string", - "description": "A link to the next page of Traits." + "description": "A link to the next page of Logs." }, "next_page_token": { "type": "string", - "description": "The page token for the next page of Traits." + "description": "The page token for the next page of Logs." }, "selfLink": { "type": "string", @@ -10926,11 +6504,11 @@ } } }, - "Trait": { - "id": "Trait", - "description": "Trait", + "Log": { + "id": "Log", + "description": "Log", "type": "object", - "uuidPrefix": "q1cn2", + "uuidPrefix": "57u5n", "properties": { "uuid": { "type": "string" @@ -10939,6 +6517,9 @@ "type": "string", "description": "Object version." }, + "id": { + "type": "integer" + }, "owner_uuid": { "type": "string" }, @@ -10948,17 +6529,29 @@ "modified_by_user_uuid": { "type": "string" }, - "modified_at": { + "object_uuid": { + "type": "string" + }, + "event_at": { "type": "datetime" }, - "name": { + "event_type": { "type": "string" }, + "summary": { + "type": "text" + }, "properties": { "type": "Hash" }, "created_at": { "type": "datetime" + }, + "modified_at": { + "type": "datetime" + }, + "object_owner_uuid": { + "type": "string" } } }, diff --git a/sdk/python/arvados/_normalize_stream.py b/sdk/python/arvados/_normalize_stream.py index c72b82be1c..81dd027f20 100644 --- a/sdk/python/arvados/_normalize_stream.py +++ b/sdk/python/arvados/_normalize_stream.py @@ -2,11 +2,10 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from . import config - import re +from . import config + def escape(path): return re.sub(r'[\\:\000-\040]', lambda m: "\\%03o" % ord(m.group(0)), path) diff --git a/sdk/python/arvados/_ranges.py b/sdk/python/arvados/_ranges.py index bb245ab2bf..75678457c9 100644 --- a/sdk/python/arvados/_ranges.py +++ b/sdk/python/arvados/_ranges.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import division -from builtins import object import logging _logger = logging.getLogger('arvados.ranges') diff --git a/sdk/python/arvados/arvfile.py b/sdk/python/arvados/arvfile.py index e0e972b5c1..de20254351 100644 --- a/sdk/python/arvados/arvfile.py +++ b/sdk/python/arvados/arvfile.py @@ -2,13 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from __future__ import division -from future import standard_library -from future.utils import listitems, listvalues -standard_library.install_aliases() -from builtins import range -from builtins import object import bz2 import collections import copy @@ -620,7 +613,7 @@ class _BlockManager(object): # A WRITABLE block with its owner.closed() implies that its # size is <= KEEP_BLOCK_SIZE/2. try: - small_blocks = [b for b in listvalues(self._bufferblocks) + small_blocks = [b for b in self._bufferblocks.values() if b.state() == _BufferBlock.WRITABLE and b.owner.closed()] except AttributeError: # Writable blocks without owner shouldn't exist. @@ -763,7 +756,7 @@ class _BlockManager(object): self.repack_small_blocks(force=True, sync=True) with self.lock: - items = listitems(self._bufferblocks) + items = list(self._bufferblocks.items()) for k,v in items: if v.state() != _BufferBlock.COMMITTED and v.owner: diff --git a/sdk/python/arvados/cache.py b/sdk/python/arvados/cache.py index 85f2b89ea2..115547cf93 100644 --- a/sdk/python/arvados/cache.py +++ b/sdk/python/arvados/cache.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import object import errno import hashlib import os diff --git a/sdk/python/arvados/collection.py b/sdk/python/arvados/collection.py index 9e6bd06071..1050d4c093 100644 --- a/sdk/python/arvados/collection.py +++ b/sdk/python/arvados/collection.py @@ -12,11 +12,6 @@ cookbook for [an introduction to using the Collection class][cookbook]. [cookbook]: https://doc.arvados.org/sdk/python/cookbook.html#working-with-collections """ -from __future__ import absolute_import -from future.utils import listitems, listvalues, viewkeys -from builtins import str -from past.builtins import basestring -from builtins import object import ciso8601 import datetime import errno @@ -419,7 +414,7 @@ class RichCollectionBase(CollectionBase): if value == self._committed: return if value: - for k,v in listitems(self._items): + for k,v in self._items.items(): v.set_committed(True) self._committed = True else: @@ -434,7 +429,7 @@ class RichCollectionBase(CollectionBase): This method does not recurse. It only iterates the contents of this collection's corresponding stream. """ - return iter(viewkeys(self._items)) + return iter(self._items) @synchronized def __getitem__(self, k: str) -> CollectionItem: @@ -492,7 +487,7 @@ class RichCollectionBase(CollectionBase): `arvados.arvfile.ArvadosFile` for every file, directly within this collection's stream. This method does not recurse. """ - return listvalues(self._items) + return list(self._items.values()) @synchronized def items(self) -> List[Tuple[str, CollectionItem]]: @@ -502,7 +497,7 @@ class RichCollectionBase(CollectionBase): `arvados.arvfile.ArvadosFile` for every file, directly within this collection's stream. This method does not recurse. """ - return listitems(self._items) + return list(self._items.items()) def exists(self, path: str) -> bool: """Indicate whether this collection includes an item at `path` @@ -548,7 +543,7 @@ class RichCollectionBase(CollectionBase): item.remove(pathcomponents[1], recursive=recursive) def _clonefrom(self, source): - for k,v in listitems(source): + for k,v in source.items(): self._items[k] = v.clone(self, k) def clone(self): @@ -612,7 +607,7 @@ class RichCollectionBase(CollectionBase): source_collection = self # Find the object - if isinstance(source, basestring): + if isinstance(source, str): source_obj = source_collection.find(source) if source_obj is None: raise IOError(errno.ENOENT, "File not found", source) @@ -1024,7 +1019,7 @@ class RichCollectionBase(CollectionBase): @synchronized def flush(self) -> None: """Upload any pending data to Keep""" - for e in listvalues(self): + for e in self.values(): e.flush() @@ -2258,7 +2253,7 @@ class ResumableCollectionWriter(CollectionWriter): return writer def check_dependencies(self): - for path, orig_stat in listitems(self._dependencies): + for path, orig_stat in self._dependencies.items(): if not S_ISREG(orig_stat[ST_MODE]): raise errors.StaleWriterStateError(u"{} not file".format(path)) try: diff --git a/sdk/python/arvados/commands/arv_copy.py b/sdk/python/arvados/commands/arv_copy.py index 7f5245db86..eccf488efb 100755 --- a/sdk/python/arvados/commands/arv_copy.py +++ b/sdk/python/arvados/commands/arv_copy.py @@ -18,12 +18,6 @@ # instances src and dst. If either of these files is not found, # arv-copy will issue an error. -from __future__ import division -from future import standard_library -from future.utils import listvalues -standard_library.install_aliases() -from past.builtins import basestring -from builtins import object import argparse import contextlib import getpass @@ -47,7 +41,6 @@ import arvados.util import arvados.commands._util as arv_cmd import arvados.commands.keepdocker import arvados.http_to_keep -import ruamel.yaml as yaml from arvados._version import __version__ @@ -168,7 +161,7 @@ def main(): exit(1) # Clean up any outstanding temp git repositories. - for d in listvalues(local_repo_dir): + for d in local_repo_dir.values(): shutil.rmtree(d, ignore_errors=True) if not result: @@ -258,10 +251,10 @@ def filter_iter(arg): Pass in a filter field that can either be a string or list. This will iterate elements as if the field had been written as a list. """ - if isinstance(arg, basestring): - return iter((arg,)) + if isinstance(arg, str): + yield arg else: - return iter(arg) + yield from arg def migrate_repository_filter(repo_filter, src_repository, dst_repository): """Update a single repository filter in-place for the destination. @@ -409,7 +402,7 @@ def copy_collections(obj, src, dst, args): collections_copied[src_id] = dst_col['uuid'] return collections_copied[src_id] - if isinstance(obj, basestring): + if isinstance(obj, str): # Copy any collections identified in this string to dst, replacing # them with the dst uuids as necessary. obj = arvados.util.portable_data_hash_pattern.sub(copy_collection_fn, obj) @@ -736,58 +729,6 @@ def copy_collection(obj_uuid, src, dst, args): c['manifest_text'] = dst_manifest.getvalue() return create_collection_from(c, src, dst, args) -def select_git_url(api, repo_name, retries, allow_insecure_http, allow_insecure_http_opt): - r = api.repositories().list( - filters=[['name', '=', repo_name]]).execute(num_retries=retries) - if r['items_available'] != 1: - raise Exception('cannot identify repo {}; {} repos found' - .format(repo_name, r['items_available'])) - - https_url = [c for c in r['items'][0]["clone_urls"] if c.startswith("https:")] - http_url = [c for c in r['items'][0]["clone_urls"] if c.startswith("http:")] - other_url = [c for c in r['items'][0]["clone_urls"] if not c.startswith("http")] - - priority = https_url + other_url + http_url - - for url in priority: - if url.startswith("http"): - u = urllib.parse.urlsplit(url) - baseurl = urllib.parse.urlunsplit((u.scheme, u.netloc, "", "", "")) - git_config = ["-c", "credential.%s/.username=none" % baseurl, - "-c", "credential.%s/.helper=!cred(){ cat >/dev/null; if [ \"$1\" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred" % baseurl] - else: - git_config = [] - - try: - logger.debug("trying %s", url) - subprocess.run( - ['git', *git_config, 'ls-remote', url], - check=True, - env={ - 'ARVADOS_API_TOKEN': api.api_token, - 'GIT_ASKPASS': '/bin/false', - 'HOME': os.environ['HOME'], - }, - stdout=subprocess.DEVNULL, - ) - except subprocess.CalledProcessError: - pass - else: - git_url = url - break - else: - raise Exception('Cannot access git repository, tried {}' - .format(priority)) - - if git_url.startswith("http:"): - if allow_insecure_http: - logger.warning("Using insecure git url %s but will allow this because %s", git_url, allow_insecure_http_opt) - else: - raise Exception("Refusing to use insecure git url %s, use %s if you really want this." % (git_url, allow_insecure_http_opt)) - - return (git_url, git_config) - - def copy_docker_image(docker_image, docker_image_tag, src, dst, args): """Copy the docker image identified by docker_image and docker_image_tag from src to dst. Create appropriate diff --git a/sdk/python/arvados/commands/ls.py b/sdk/python/arvados/commands/ls.py index ac038f5040..d67f5cc453 100644 --- a/sdk/python/arvados/commands/ls.py +++ b/sdk/python/arvados/commands/ls.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import division - import argparse import collections import logging diff --git a/sdk/python/arvados/commands/migrate19.py b/sdk/python/arvados/commands/migrate19.py index 2fef419ee8..24d6bc5045 100644 --- a/sdk/python/arvados/commands/migrate19.py +++ b/sdk/python/arvados/commands/migrate19.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import division import argparse import time import sys diff --git a/sdk/python/arvados/commands/put.py b/sdk/python/arvados/commands/put.py index 0e732eafde..d1961c8c8a 100644 --- a/sdk/python/arvados/commands/put.py +++ b/sdk/python/arvados/commands/put.py @@ -2,10 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import division -from future.utils import listitems, listvalues -from builtins import str -from builtins import object import argparse import arvados import arvados.collection @@ -696,7 +692,7 @@ class ArvPutUploadJob(object): Recursively get the total size of the collection """ size = 0 - for item in listvalues(collection): + for item in collection.values(): if isinstance(item, arvados.collection.Collection) or isinstance(item, arvados.collection.Subcollection): size += self._collection_size(item) else: @@ -978,7 +974,7 @@ class ArvPutUploadJob(object): def collection_file_paths(self, col, path_prefix='.'): """Return a list of file paths by recursively go through the entire collection `col`""" file_paths = [] - for name, item in listitems(col): + for name, item in col.items(): if isinstance(item, arvados.arvfile.ArvadosFile): file_paths.append(os.path.join(path_prefix, name)) elif isinstance(item, arvados.collection.Subcollection): @@ -1058,7 +1054,7 @@ class ArvPutUploadJob(object): locators.append(loc) return locators elif isinstance(item, arvados.collection.Collection): - l = [self._datablocks_on_item(x) for x in listvalues(item)] + l = [self._datablocks_on_item(x) for x in item.values()] # Fast list flattener method taken from: # http://stackoverflow.com/questions/952914/making-a-flat-list-out-of-list-of-lists-in-python return [loc for sublist in l for loc in sublist] diff --git a/sdk/python/arvados/commands/run.py b/sdk/python/arvados/commands/run.py index 0fe05da22b..474111d882 100644 --- a/sdk/python/arvados/commands/run.py +++ b/sdk/python/arvados/commands/run.py @@ -15,11 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -from __future__ import print_function -from __future__ import absolute_import -from builtins import range -from past.builtins import basestring -from builtins import object import arvados import arvados.commands.ws as ws import argparse diff --git a/sdk/python/arvados/commands/ws.py b/sdk/python/arvados/commands/ws.py index 04a90cf20b..3508682399 100644 --- a/sdk/python/arvados/commands/ws.py +++ b/sdk/python/arvados/commands/ws.py @@ -2,16 +2,16 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -import sys -import logging import argparse -import arvados import json +import logging +import signal +import sys + +import arvados from arvados.events import subscribe from arvados._version import __version__ from . import _util as arv_cmd -import signal def main(arguments=None): logger = logging.getLogger('arvados.arv-ws') diff --git a/sdk/python/arvados/crunch.py b/sdk/python/arvados/crunch.py index 6dd144c43b..57cf2e01ef 100644 --- a/sdk/python/arvados/crunch.py +++ b/sdk/python/arvados/crunch.py @@ -2,9 +2,9 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import object import json import os + from . import util class TaskOutputDir(object): diff --git a/sdk/python/arvados/keep.py b/sdk/python/arvados/keep.py index d1be6b931e..5501b84271 100644 --- a/sdk/python/arvados/keep.py +++ b/sdk/python/arvados/keep.py @@ -2,16 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from __future__ import division import copy -from future import standard_library -from future.utils import native_str -standard_library.install_aliases() -from builtins import next -from builtins import str -from builtins import range -from builtins import object import collections import datetime import hashlib @@ -28,15 +19,11 @@ import ssl import sys import threading import resource -from . import timer import urllib.parse import traceback import weakref -if sys.version_info >= (3, 0): - from io import BytesIO -else: - from cStringIO import StringIO as BytesIO +from io import BytesIO import arvados import arvados.config as config @@ -45,11 +32,11 @@ import arvados.retry as retry import arvados.util import arvados.diskcache from arvados._pycurlhelper import PyCurlHelper +from . import timer _logger = logging.getLogger('arvados.keep') global_client_object = None - # Monkey patch TCP constants when not available (apple). Values sourced from: # http://www.opensource.apple.com/source/xnu/xnu-2422.115.4/bsd/netinet/tcp.h if sys.platform == 'darwin': @@ -60,7 +47,6 @@ if sys.platform == 'darwin': if not hasattr(socket, 'TCP_KEEPCNT'): socket.TCP_KEEPCNT = 0x102 - class KeepLocator(object): EPOCH_DATETIME = datetime.datetime.utcfromtimestamp(0) HINT_RE = re.compile(r'^[A-Z][A-Za-z0-9@_-]+$') @@ -85,7 +71,7 @@ class KeepLocator(object): def __str__(self): return '+'.join( - native_str(s) + str(s) for s in [self.md5sum, self.size, self.permission_hint()] + self.hints if s is not None) diff --git a/sdk/python/arvados/stream.py b/sdk/python/arvados/stream.py index 37cd5d7db8..ff541e5716 100644 --- a/sdk/python/arvados/stream.py +++ b/sdk/python/arvados/stream.py @@ -2,10 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import absolute_import -from future.utils import listvalues -from builtins import object import collections import hashlib import os @@ -70,7 +66,7 @@ class StreamReader(object): return self._files def all_files(self): - return listvalues(self._files) + return list(self._files.values()) def size(self): n = self._data_locators[-1] @@ -105,5 +101,5 @@ class StreamReader(object): manifest_text.extend([d.locator for d in self._data_locators]) manifest_text.extend([' '.join(["{}:{}:{}".format(seg.locator, seg.range_size, f.name.replace(' ', '\\040')) for seg in f.segments]) - for f in listvalues(self._files)]) + for f in self._files.values()]) return ' '.join(manifest_text) + '\n' diff --git a/sdk/python/arvados/timer.py b/sdk/python/arvados/timer.py index 97bc38add0..39dbc7874e 100644 --- a/sdk/python/arvados/timer.py +++ b/sdk/python/arvados/timer.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from builtins import object import time class Timer(object): diff --git a/sdk/python/arvados_version.py b/sdk/python/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/sdk/python/arvados_version.py +++ b/sdk/python/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/sdk/python/pytest.ini b/sdk/python/pytest.ini new file mode 100644 index 0000000000..9b1bbfd50a --- /dev/null +++ b/sdk/python/pytest.ini @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + +[pytest] +testpaths = + tests diff --git a/sdk/python/setup.py b/sdk/python/setup.py index e13e51609a..dc10269060 100644 --- a/sdk/python/setup.py +++ b/sdk/python/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import os import sys import re @@ -14,7 +13,6 @@ from setuptools.command import build_py import arvados_version version = arvados_version.get_version() -short_tests_only = arvados_version.short_tests_only() README = os.path.join(arvados_version.SETUP_DIR, 'README.rst') class BuildPython(build_py.build_py): @@ -111,15 +109,10 @@ setup(name='arvados-python-client', install_requires=[ *arvados_version.iter_dependencies(version), 'ciso8601 >=2.0.0', - 'future', - 'google-api-core <2.11.0', # 2.11.0rc1 is incompatible with google-auth<2 'google-api-python-client >=2.1.0', - 'google-auth <2', - 'httplib2 >=0.9.2, <0.20.2', - 'protobuf <4.0.0dev', - 'pycurl >=7.19.5.1, <7.45.0', - 'pyparsing <3', - 'ruamel.yaml >=0.15.54, <0.17.22', + 'google-auth', + 'httplib2 >=0.9.2', + 'pycurl >=7.19.5.1', 'setuptools >=40.3.0', 'websockets >=11.0', ], @@ -128,6 +121,6 @@ setup(name='arvados-python-client', 'Programming Language :: Python :: 3', ], test_suite='tests', - tests_require=['pbr<1.7.0', 'mock>=1.0,<4', 'PyYAML', 'parameterized'], + tests_require=['PyYAML', 'parameterized'], zip_safe=False ) diff --git a/sdk/python/tests/arvados_testutil.py b/sdk/python/tests/arvados_testutil.py index 35e85d1195..1f1f796a9c 100644 --- a/sdk/python/tests/arvados_testutil.py +++ b/sdk/python/tests/arvados_testutil.py @@ -2,11 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() -from builtins import str -from builtins import range -from builtins import object import arvados import contextlib import errno @@ -14,7 +9,6 @@ import hashlib import http.client import httplib2 import io -import mock import os import pycurl import queue @@ -23,11 +17,8 @@ import sys import tempfile import unittest -if sys.version_info >= (3, 0): - from io import StringIO, BytesIO -else: - from cStringIO import StringIO - BytesIO = StringIO +from io import StringIO, BytesIO +from unittest import mock # Use this hostname when you want to make sure the traffic will be # instantly refused. 100::/64 is a dedicated black hole. diff --git a/sdk/python/tests/keepstub.py b/sdk/python/tests/keepstub.py index 6be8d8b646..a4deb5384b 100644 --- a/sdk/python/tests/keepstub.py +++ b/sdk/python/tests/keepstub.py @@ -2,10 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import division -from future import standard_library -standard_library.install_aliases() -from builtins import str import http.server import hashlib import os @@ -20,9 +16,7 @@ from . import arvados_testutil as tutil _debug = os.environ.get('ARVADOS_DEBUG', None) - class StubKeepServers(tutil.ApiClientMock): - def setUp(self): super(StubKeepServers, self).setUp() sock = socket.socket() diff --git a/sdk/python/tests/manifest_examples.py b/sdk/python/tests/manifest_examples.py index 050d69093c..c1945d03d9 100644 --- a/sdk/python/tests/manifest_examples.py +++ b/sdk/python/tests/manifest_examples.py @@ -2,10 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import range -from builtins import object import arvados + from . import arvados_testutil as tutil class ManifestExamples(object): diff --git a/sdk/python/tests/nginx.conf b/sdk/python/tests/nginx.conf index 446b95ca42..a382d643ef 100644 --- a/sdk/python/tests/nginx.conf +++ b/sdk/python/tests/nginx.conf @@ -46,22 +46,6 @@ http { proxy_http_version 1.1; } } - upstream arv-git-http { - server {{UPSTREAMHOST}}:{{GITPORT}}; - } - server { - listen {{LISTENHOST}}:{{GITSSLPORT}} ssl; - server_name arv-git-http git.*; - ssl_certificate "{{SSLCERT}}"; - ssl_certificate_key "{{SSLKEY}}"; - location / { - proxy_pass http://arv-git-http; - proxy_set_header Host $http_host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header X-Forwarded-Proto https; - proxy_redirect off; - } - } upstream keepproxy { server {{UPSTREAMHOST}}:{{KEEPPROXYPORT}}; } diff --git a/sdk/python/tests/performance/test_a_sample.py b/sdk/python/tests/performance/test_a_sample.py index 65015dc872..9e54b1f5d2 100644 --- a/sdk/python/tests/performance/test_a_sample.py +++ b/sdk/python/tests/performance/test_a_sample.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import absolute_import -from builtins import range import unittest from .performance_profiler import profiled diff --git a/sdk/python/tests/run_test_server.py b/sdk/python/tests/run_test_server.py index 787837b723..d5a3db1f5d 100644 --- a/sdk/python/tests/run_test_server.py +++ b/sdk/python/tests/run_test_server.py @@ -328,13 +328,6 @@ def run(leave_running_atexit=False): if not os.path.exists('tmp/logs'): os.makedirs('tmp/logs') - # Install the git repository fixtures. - gitdir = os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git') - gittarball = os.path.join(SERVICES_SRC_DIR, 'api', 'test', 'test.git.tar') - if not os.path.isdir(gitdir): - os.makedirs(gitdir) - subprocess.check_output(['tar', '-xC', gitdir, '-f', gittarball]) - # Customizing the passenger config template is the only documented # way to override the default passenger_stat_throttle_rate (10 s). # In the testing environment, we want restart.txt to take effect @@ -524,8 +517,6 @@ def run_keep(num_servers=2, **kwargs): for d in api.keep_services().list(filters=[['service_type','=','disk']]).execute()['items']: api.keep_services().delete(uuid=d['uuid']).execute() - for d in api.keep_disks().list().execute()['items']: - api.keep_disks().delete(uuid=d['uuid']).execute() for d in range(0, num_servers): port = _start_keep(d, **kwargs) @@ -536,9 +527,6 @@ def run_keep(num_servers=2, **kwargs): 'service_type': 'disk', 'service_ssl_flag': False, }}).execute() - api.keep_disks().create(body={ - 'keep_disk': {'keep_service_uuid': svc['uuid'] } - }).execute() # If keepproxy and/or keep-web is running, send SIGHUP to make # them discover the new keepstore services. @@ -599,27 +587,6 @@ def stop_keep_proxy(): return kill_server_pid(_pidfile('keepproxy')) -def run_arv_git_httpd(): - if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ: - return - stop_arv_git_httpd() - - gitport = internal_port_from_config("GitHTTP") - env = os.environ.copy() - env.pop('ARVADOS_API_TOKEN', None) - logf = open(_logfilename('githttpd'), WRITE_MODE) - agh = subprocess.Popen(['arvados-server', 'git-httpd'], - env=env, stdin=open('/dev/null'), stdout=logf, stderr=logf) - _detachedSubprocesses.append(agh) - with open(_pidfile('githttpd'), 'w') as f: - f.write(str(agh.pid)) - _wait_until_port_listens(gitport) - -def stop_arv_git_httpd(): - if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ: - return - kill_server_pid(_pidfile('githttpd')) - def run_keep_web(): if 'ARVADOS_TEST_PROXY_SERVICES' in os.environ: return @@ -656,8 +623,6 @@ def run_nginx(): nginxconf['KEEPWEBSSLPORT'] = external_port_from_config("WebDAV") nginxconf['KEEPPROXYPORT'] = internal_port_from_config("Keepproxy") nginxconf['KEEPPROXYSSLPORT'] = external_port_from_config("Keepproxy") - nginxconf['GITPORT'] = internal_port_from_config("GitHTTP") - nginxconf['GITSSLPORT'] = external_port_from_config("GitHTTP") nginxconf['HEALTHPORT'] = internal_port_from_config("Health") nginxconf['HEALTHSSLPORT'] = external_port_from_config("Health") nginxconf['WSPORT'] = internal_port_from_config("Websocket") @@ -685,7 +650,7 @@ def run_nginx(): nginx = subprocess.Popen( ['nginx', - '-g', 'error_log stderr info; pid '+_pidfile('nginx')+';', + '-g', 'error_log stderr notice; pid '+_pidfile('nginx')+';', '-c', conffile], env=env, stdin=open('/dev/null'), stdout=sys.stderr) _detachedSubprocesses.append(nginx) @@ -700,8 +665,6 @@ def setup_config(): workbench1_external_port = find_available_port() workbench2_port = find_available_port() workbench2_external_port = find_available_port() - git_httpd_port = find_available_port() - git_httpd_external_port = find_available_port() health_httpd_port = find_available_port() health_httpd_external_port = find_available_port() keepproxy_port = find_available_port() @@ -755,12 +718,6 @@ def setup_config(): "http://%s:%s"%(localhost, workbench2_port): {}, }, }, - "GitHTTP": { - "ExternalURL": "https://%s:%s" % (localhost, git_httpd_external_port), - "InternalURLs": { - "http://%s:%s"%(localhost, git_httpd_port): {} - }, - }, "Health": { "ExternalURL": "https://%s:%s" % (localhost, health_httpd_external_port), "InternalURLs": { @@ -831,19 +788,10 @@ def setup_config(): "BlobSigningKey": "zfhgfenhffzltr9dixws36j1yhksjoll2grmku38mi7yxd66h5j4q9w4jzanezacp8s6q0ro3hxakfye02152hncy6zml2ed0uc", "TrustAllContent": False, "ForwardSlashNameSubstitution": "/", - "TrashSweepInterval": "-1s", - }, - "Git": { - "Repositories": os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'git', 'test'), + "TrashSweepInterval": "-1s", # disable, otherwise test cases can't acquire dblock }, "Containers": { - "JobsAPI": { - "GitInternalDir": os.path.join(SERVICES_SRC_DIR, 'api', 'tmp', 'internal.git'), - }, "LocalKeepBlobBuffersPerVCPU": 0, - "Logging": { - "SweepInterval": 0, # disable, otherwise test cases can't acquire dblock - }, "SupportedDockerImageFormats": {"v1": {}}, "ShellAccess": { "Admin": True, @@ -971,7 +919,6 @@ if __name__ == "__main__": 'start_keep', 'stop_keep', 'start_keep_proxy', 'stop_keep_proxy', 'start_keep-web', 'stop_keep-web', - 'start_githttpd', 'stop_githttpd', 'start_nginx', 'stop_nginx', 'setup_config', ] parser = argparse.ArgumentParser() @@ -1019,10 +966,6 @@ if __name__ == "__main__": run_keep_proxy() elif args.action == 'stop_keep_proxy': stop_keep_proxy() - elif args.action == 'start_githttpd': - run_arv_git_httpd() - elif args.action == 'stop_githttpd': - stop_arv_git_httpd() elif args.action == 'start_keep-web': run_keep_web() elif args.action == 'stop_keep-web': diff --git a/sdk/python/tests/slow_test.py b/sdk/python/tests/slow_test.py deleted file mode 100644 index ae46f4e1bf..0000000000 --- a/sdk/python/tests/slow_test.py +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: Apache-2.0 - -import __main__ -import os -import unittest - -slow_test = lambda _: unittest.skipIf( - __main__.short_tests_only, - "running --short tests only") diff --git a/sdk/python/tests/test_api.py b/sdk/python/tests/test_api.py index 0f85e5520c..7d7cc9ba59 100644 --- a/sdk/python/tests/test_api.py +++ b/sdk/python/tests/test_api.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import str -from builtins import range import arvados import collections import contextlib @@ -20,7 +17,7 @@ import sys import unittest import urllib.parse as urlparse -import mock +from unittest import mock from . import run_test_server from apiclient import errors as apiclient_errors @@ -70,8 +67,8 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): self.assertIsNot(*clients) def test_empty_list(self): - answer = arvados.api('v1').humans().list( - filters=[['uuid', '=', None]]).execute() + answer = arvados.api('v1').collections().list( + filters=[['uuid', '=', 'abcdef']]).execute() self.assertEqual(answer['items_available'], len(answer['items'])) def test_nonempty_list(self): @@ -81,11 +78,11 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): def test_timestamp_inequality_filter(self): api = arvados.api('v1') - new_item = api.specimens().create(body={}).execute() + new_item = api.collections().create(body={}).execute() for operator, should_include in [ ['<', False], ['>', False], ['<=', True], ['>=', True], ['=', True]]: - response = api.specimens().list(filters=[ + response = api.collections().list(filters=[ ['created_at', operator, new_item['created_at']], # Also filter by uuid to ensure (if it matches) it's on page 0 ['uuid', '=', new_item['uuid']]]).execute() @@ -100,13 +97,13 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): def test_exceptions_include_errors(self): mock_responses = { - 'arvados.humans.get': self.api_error_response( + 'arvados.collections.get': self.api_error_response( 422, "Bad UUID format", "Bad output format"), } req_builder = apiclient_http.RequestMockBuilder(mock_responses) api = arvados.api('v1', requestBuilder=req_builder) with self.assertRaises(apiclient_errors.HttpError) as err_ctx: - api.humans().get(uuid='xyz-xyz-abcdef').execute() + api.collections().get(uuid='xyz-xyz-abcdef').execute() err_s = str(err_ctx.exception) for msg in ["Bad UUID format", "Bad output format"]: self.assertIn(msg, err_s) @@ -126,14 +123,14 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): def test_exceptions_without_errors_have_basic_info(self): mock_responses = { - 'arvados.humans.delete': ( + 'arvados.collections.delete': ( fake_httplib2_response(500, **self.ERROR_HEADERS), b"") } req_builder = apiclient_http.RequestMockBuilder(mock_responses) api = arvados.api('v1', requestBuilder=req_builder) with self.assertRaises(apiclient_errors.HttpError) as err_ctx: - api.humans().delete(uuid='xyz-xyz-abcdef').execute() + api.collections().delete(uuid='xyz-xyz-abcdef').execute() self.assertIn("500", str(err_ctx.exception)) def test_request_too_large(self): @@ -206,7 +203,7 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): def test_ordered_json_model(self): mock_responses = { - 'arvados.humans.get': ( + 'arvados.collections.get': ( None, json.dumps(collections.OrderedDict( (c, int(c, 16)) for c in string.hexdigits @@ -216,7 +213,7 @@ class ArvadosApiTest(run_test_server.TestCaseWithServers): req_builder = apiclient_http.RequestMockBuilder(mock_responses) api = arvados.api('v1', requestBuilder=req_builder, model=OrderedJsonModel()) - result = api.humans().get(uuid='test').execute() + result = api.collections().get(uuid='test').execute() self.assertEqual(string.hexdigits, ''.join(list(result.keys()))) def test_api_is_threadsafe(self): diff --git a/sdk/python/tests/test_arv_copy.py b/sdk/python/tests/test_arv_copy.py index b853b33043..1af5c68e6c 100644 --- a/sdk/python/tests/test_arv_copy.py +++ b/sdk/python/tests/test_arv_copy.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import os import sys import tempfile diff --git a/sdk/python/tests/test_arv_get.py b/sdk/python/tests/test_arv_get.py index d12739f6f6..aefcbd7b22 100644 --- a/sdk/python/tests/test_arv_get.py +++ b/sdk/python/tests/test_arv_get.py @@ -2,16 +2,15 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from future.utils import listitems import io import logging -import mock import os import re import shutil import tempfile +from unittest import mock + import arvados import arvados.collection as collection import arvados.commands.get as arv_get @@ -51,7 +50,7 @@ class ArvadosGetTestCase(run_test_server.TestCaseWithServers, }): api = arvados.api() c = collection.Collection(api_client=api) - for path, data in listitems(contents): + for path, data in contents.items(): with c.open(path, 'wb') as f: f.write(data) c.save_new() diff --git a/sdk/python/tests/test_arv_keepdocker.py b/sdk/python/tests/test_arv_keepdocker.py index 9aebc03504..5d23dfb378 100644 --- a/sdk/python/tests/test_arv_keepdocker.py +++ b/sdk/python/tests/test_arv_keepdocker.py @@ -8,13 +8,14 @@ import collections.abc import copy import hashlib import logging -import mock import os import subprocess import sys import tempfile import unittest + from pathlib import Path +from unittest import mock import parameterized diff --git a/sdk/python/tests/test_arv_ls.py b/sdk/python/tests/test_arv_ls.py index 635c6254ad..59441a74c2 100644 --- a/sdk/python/tests/test_arv_ls.py +++ b/sdk/python/tests/test_arv_ls.py @@ -2,15 +2,13 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import str -from builtins import range import os import random import sys -import mock import tempfile +from unittest import mock + import arvados.errors as arv_error import arvados.commands.ls as arv_ls from . import run_test_server diff --git a/sdk/python/tests/test_arv_put.py b/sdk/python/tests/test_arv_put.py index afdf2238a7..e8a3e65bdc 100644 --- a/sdk/python/tests/test_arv_put.py +++ b/sdk/python/tests/test_arv_put.py @@ -4,19 +4,12 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from __future__ import division -from future import standard_library -standard_library.install_aliases() -from builtins import str -from builtins import range -from functools import partial import apiclient import ciso8601 +import copy import datetime import json import logging -import mock import multiprocessing import os import pwd @@ -32,6 +25,9 @@ import time import unittest import uuid +from functools import partial +from unittest import mock + import arvados import arvados.commands.put as arv_put from . import arvados_testutil as tutil @@ -573,7 +569,7 @@ class ArvPutUploadJobTest(run_test_server.TestCaseWithServers, class CachedManifestValidationTest(ArvadosBaseTestCase): class MockedPut(arv_put.ArvPutUploadJob): def __init__(self, cached_manifest=None): - self._state = arv_put.ArvPutUploadJob.EMPTY_STATE + self._state = copy.deepcopy(arv_put.ArvPutUploadJob.EMPTY_STATE) self._state['manifest'] = cached_manifest self._api_client = mock.MagicMock() self.logger = mock.MagicMock() diff --git a/sdk/python/tests/test_arv_ws.py b/sdk/python/tests/test_arv_ws.py index 521c46ee34..4e67db2184 100644 --- a/sdk/python/tests/test_arv_ws.py +++ b/sdk/python/tests/test_arv_ws.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import os import sys import tempfile diff --git a/sdk/python/tests/test_arvfile.py b/sdk/python/tests/test_arvfile.py index 600f17baad..6bcba9a81d 100644 --- a/sdk/python/tests/test_arvfile.py +++ b/sdk/python/tests/test_arvfile.py @@ -2,16 +2,12 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import hex -from builtins import str -from builtins import range -from builtins import object import datetime -import mock import os -import unittest import time +import unittest + +from unittest import mock import arvados from arvados._ranges import Range diff --git a/sdk/python/tests/test_benchmark_collections.py b/sdk/python/tests/test_benchmark_collections.py index fc062e791c..0014e94af2 100644 --- a/sdk/python/tests/test_benchmark_collections.py +++ b/sdk/python/tests/test_benchmark_collections.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import arvados import sys diff --git a/sdk/python/tests/test_cache.py b/sdk/python/tests/test_cache.py index 259acd0a30..41984a5bf9 100644 --- a/sdk/python/tests/test_cache.py +++ b/sdk/python/tests/test_cache.py @@ -2,13 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import print_function -from __future__ import absolute_import - -from builtins import str -from builtins import range import hashlib -import mock import os import random import shutil @@ -17,11 +11,12 @@ import tempfile import threading import unittest +from unittest import mock + import arvados import arvados.cache from . import run_test_server - def _random(n): return bytearray(random.getrandbits(8) for _ in range(n)) diff --git a/sdk/python/tests/test_collections.py b/sdk/python/tests/test_collections.py index 9e753506b3..5d574856dd 100644 --- a/sdk/python/tests/test_collections.py +++ b/sdk/python/tests/test_collections.py @@ -2,12 +2,8 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import - -from builtins import object import arvados import copy -import mock import os import random import re @@ -18,6 +14,8 @@ import time import unittest import parameterized +from unittest import mock + from . import run_test_server from arvados._ranges import Range, LocatorAndRange from arvados.collection import Collection, CollectionReader diff --git a/sdk/python/tests/test_errors.py b/sdk/python/tests/test_errors.py index 4ee68ba285..02f316bf79 100644 --- a/sdk/python/tests/test_errors.py +++ b/sdk/python/tests/test_errors.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import import traceback import unittest diff --git a/sdk/python/tests/test_events.py b/sdk/python/tests/test_events.py index b4e6a0b1cd..c5f3310015 100644 --- a/sdk/python/tests/test_events.py +++ b/sdk/python/tests/test_events.py @@ -4,13 +4,14 @@ import json import logging -import mock import queue import sys import threading import time import unittest +from unittest import mock + import websockets.exceptions as ws_exc import arvados @@ -96,9 +97,9 @@ class WebsocketTest(run_test_server.TestCaseWithServers): # Create ancestor before subscribing. # When listening with start_time in the past, this should also be retrieved. # However, when start_time is omitted in subscribe, this should not be fetched. - ancestor = arvados.api('v1').humans().create(body={}).execute() + ancestor = arvados.api('v1').collections().create(body={}).execute() - filters = [['object_uuid', 'is_a', 'arvados#human']] + filters = [['object_uuid', 'is_a', 'arvados#collection']] if start_time: filters.append(['created_at', '>=', start_time]) @@ -117,11 +118,11 @@ class WebsocketTest(run_test_server.TestCaseWithServers): while not self.ws._skip_old_events: self.assertLess(time.time(), deadline) time.sleep(0.1) - human = arvados.api('v1').humans().create(body={}).execute() + collection = arvados.api('v1').collections().create(body={}).execute() want_uuids = [] if expected > 0: - want_uuids.append(human['uuid']) + want_uuids.append(collection['uuid']) if expected > 1: want_uuids.append(ancestor['uuid']) log_object_uuids = [] @@ -227,7 +228,7 @@ class WebsocketTest(run_test_server.TestCaseWithServers): streamHandler = logging.StreamHandler(logstream) rootLogger.addHandler(streamHandler) - filters = [['object_uuid', 'is_a', 'arvados#human']] + filters = [['object_uuid', 'is_a', 'arvados#collection']] filters.append(['created_at', '>=', self.localiso(self.TIME_PAST)]) self.ws = arvados.events.subscribe( arvados.api('v1'), filters, @@ -238,10 +239,10 @@ class WebsocketTest(run_test_server.TestCaseWithServers): self.assertEqual(200, events.get(True, 5)['status']) # create obj - human = arvados.api('v1').humans().create(body={}).execute() + collection = arvados.api('v1').collections().create(body={}).execute() # expect an event - self.assertIn(human['uuid'], events.get(True, 5)['object_uuid']) + self.assertIn(collection['uuid'], events.get(True, 5)['object_uuid']) with self.assertRaises(queue.Empty): self.assertEqual(events.get(True, 2), None) @@ -252,7 +253,7 @@ class WebsocketTest(run_test_server.TestCaseWithServers): self.ws.close() # create one more obj - human2 = arvados.api('v1').humans().create(body={}).execute() + collection2 = arvados.api('v1').collections().create(body={}).execute() # (un)expect the object creation event if close_unexpected: @@ -263,8 +264,8 @@ class WebsocketTest(run_test_server.TestCaseWithServers): log_object_uuids.append(event['object_uuid']) with self.assertRaises(queue.Empty): self.assertEqual(events.get(True, 2), None) - self.assertNotIn(human['uuid'], log_object_uuids) - self.assertIn(human2['uuid'], log_object_uuids) + self.assertNotIn(collection['uuid'], log_object_uuids) + self.assertIn(collection2['uuid'], log_object_uuids) else: with self.assertRaises(queue.Empty): self.assertEqual(events.get(True, 2), None) diff --git a/sdk/python/tests/test_http.py b/sdk/python/tests/test_http.py index bce57eda61..476e2c88e9 100644 --- a/sdk/python/tests/test_http.py +++ b/sdk/python/tests/test_http.py @@ -2,20 +2,18 @@ # # SPDX-License-Identifier: Apache-2.0 -from future import standard_library -standard_library.install_aliases() - import copy import io import functools import hashlib import json import logging -import mock import sys import unittest import datetime +from unittest import mock + import arvados import arvados.collection import arvados.keep @@ -23,8 +21,6 @@ import pycurl from arvados.http_to_keep import http_to_keep -import ruamel.yaml as yaml - # Turns out there was already "FakeCurl" that serves the same purpose, but # I wrote this before I knew that. Whoops. class CurlMock: diff --git a/sdk/python/tests/test_keep_client.py b/sdk/python/tests/test_keep_client.py index 8c0f096b61..2dc4363f0c 100644 --- a/sdk/python/tests/test_keep_client.py +++ b/sdk/python/tests/test_keep_client.py @@ -2,16 +2,7 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from __future__ import division -from future import standard_library -standard_library.install_aliases() -from builtins import str -from builtins import range -from builtins import object import hashlib -import mock -from mock import patch import os import errno import pycurl @@ -27,6 +18,9 @@ import unittest import urllib.parse import mmap +from unittest import mock +from unittest.mock import patch + import parameterized import arvados diff --git a/sdk/python/tests/test_keep_locator.py b/sdk/python/tests/test_keep_locator.py index e47d64d337..bc93f403a0 100644 --- a/sdk/python/tests/test_keep_locator.py +++ b/sdk/python/tests/test_keep_locator.py @@ -2,10 +2,6 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import next -from builtins import zip -from builtins import str -from builtins import range import datetime import itertools import random diff --git a/sdk/python/tests/test_retry.py b/sdk/python/tests/test_retry.py index bcf784d130..c6e713244c 100644 --- a/sdk/python/tests/test_retry.py +++ b/sdk/python/tests/test_retry.py @@ -2,15 +2,13 @@ # # SPDX-License-Identifier: Apache-2.0 -from builtins import zip -from builtins import range -from builtins import object import itertools import unittest +from unittest import mock + import arvados.errors as arv_error import arvados.retry as arv_retry -import mock class RetryLoopTestMixin(object): @staticmethod diff --git a/sdk/python/tests/test_retry_job_helpers.py b/sdk/python/tests/test_retry_job_helpers.py index 9389b25c88..a5a6bb22c1 100644 --- a/sdk/python/tests/test_retry_job_helpers.py +++ b/sdk/python/tests/test_retry_job_helpers.py @@ -2,18 +2,17 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import object -import mock -import os -import unittest import hashlib -from . import run_test_server import json -import arvados -from . import arvados_testutil as tutil +import os +import unittest + from apiclient import http as apiclient_http +from unittest import mock +import arvados +from . import run_test_server +from . import arvados_testutil as tutil @tutil.skip_sleep class ApiClientRetryTestMixin(object): @@ -57,22 +56,3 @@ class ApiClientRetryTestMixin(object): def test_no_retry_after_immediate_success(self): with tutil.mock_api_responses(self.api_client, '{}', [200, 400]): self.run_method() - - -class CurrentJobTestCase(ApiClientRetryTestMixin, unittest.TestCase): - - DEFAULT_EXCEPTION = arvados.errors.ApiError - - def setUp(self): - super(CurrentJobTestCase, self).setUp() - os.environ['JOB_UUID'] = 'zzzzz-zzzzz-zzzzzzzzzzzzzzz' - os.environ['JOB_WORK'] = '.' - - def tearDown(self): - del os.environ['JOB_UUID'] - del os.environ['JOB_WORK'] - arvados._current_job = None - super(CurrentJobTestCase, self).tearDown() - - def run_method(self): - arvados.current_job() diff --git a/sdk/python/tests/test_sdk.py b/sdk/python/tests/test_sdk.py index 41add57c0e..4ef81c53d8 100644 --- a/sdk/python/tests/test_sdk.py +++ b/sdk/python/tests/test_sdk.py @@ -2,10 +2,11 @@ # # SPDX-License-Identifier: Apache-2.0 -import mock import os import unittest +from unittest import mock + import arvados import arvados.collection diff --git a/sdk/python/tests/test_stream.py b/sdk/python/tests/test_stream.py index 12a3340eab..a3f5d9ff63 100644 --- a/sdk/python/tests/test_stream.py +++ b/sdk/python/tests/test_stream.py @@ -2,16 +2,15 @@ # # SPDX-License-Identifier: Apache-2.0 -from __future__ import absolute_import -from builtins import object import bz2 import gzip import io -import mock import os import unittest import hashlib +from unittest import mock + import arvados from arvados import StreamReader, StreamFileReader from arvados._ranges import Range diff --git a/sdk/python/tests/test_vocabulary.py b/sdk/python/tests/test_vocabulary.py index aa2e739e20..2f5db3b9d9 100644 --- a/sdk/python/tests/test_vocabulary.py +++ b/sdk/python/tests/test_vocabulary.py @@ -4,7 +4,8 @@ import arvados import unittest -import mock + +from unittest import mock from arvados import api, vocabulary diff --git a/services/api/Gemfile.lock b/services/api/Gemfile.lock index 0fe91e0a18..8b1bbdfc87 100644 --- a/services/api/Gemfile.lock +++ b/services/api/Gemfile.lock @@ -320,4 +320,4 @@ DEPENDENCIES webrick BUNDLED WITH - 2.4.19 + 2.4.22 diff --git a/services/api/app/assets/stylesheets/api_client_authorizations.css.scss b/services/api/app/assets/stylesheets/api_client_authorizations.css.scss deleted file mode 100644 index ec87eb255f..0000000000 --- a/services/api/app/assets/stylesheets/api_client_authorizations.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the ApiClientAuthorizations controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/api_clients.css.scss b/services/api/app/assets/stylesheets/api_clients.css.scss deleted file mode 100644 index 61d7e53aa6..0000000000 --- a/services/api/app/assets/stylesheets/api_clients.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the ApiClients controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/authorized_keys.css.scss b/services/api/app/assets/stylesheets/authorized_keys.css.scss deleted file mode 100644 index 9eeaa89f3f..0000000000 --- a/services/api/app/assets/stylesheets/authorized_keys.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the AuthorizedKeys controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/collections.css.scss b/services/api/app/assets/stylesheets/collections.css.scss deleted file mode 100644 index 7510f173b9..0000000000 --- a/services/api/app/assets/stylesheets/collections.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Collections controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/commit_ancestors.css.scss b/services/api/app/assets/stylesheets/commit_ancestors.css.scss deleted file mode 100644 index 5004f86911..0000000000 --- a/services/api/app/assets/stylesheets/commit_ancestors.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the commit_ancestors controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/commits.css.scss b/services/api/app/assets/stylesheets/commits.css.scss deleted file mode 100644 index 6b4df4d74f..0000000000 --- a/services/api/app/assets/stylesheets/commits.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the commits controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/groups.css.scss b/services/api/app/assets/stylesheets/groups.css.scss deleted file mode 100644 index 905e72add9..0000000000 --- a/services/api/app/assets/stylesheets/groups.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Groups controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/humans.css.scss b/services/api/app/assets/stylesheets/humans.css.scss deleted file mode 100644 index 29668c2737..0000000000 --- a/services/api/app/assets/stylesheets/humans.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Humans controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/job_tasks.css.scss b/services/api/app/assets/stylesheets/job_tasks.css.scss deleted file mode 100644 index 0d4d2607bb..0000000000 --- a/services/api/app/assets/stylesheets/job_tasks.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the JobTasks controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/jobs.css.scss b/services/api/app/assets/stylesheets/jobs.css.scss deleted file mode 100644 index 53b6ca7fbe..0000000000 --- a/services/api/app/assets/stylesheets/jobs.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Jobs controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/keep_disks.css.scss b/services/api/app/assets/stylesheets/keep_disks.css.scss deleted file mode 100644 index 1996f11635..0000000000 --- a/services/api/app/assets/stylesheets/keep_disks.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the KeepDisks controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/links.css.scss b/services/api/app/assets/stylesheets/links.css.scss deleted file mode 100644 index c2e90adf09..0000000000 --- a/services/api/app/assets/stylesheets/links.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the links controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/logs.css.scss b/services/api/app/assets/stylesheets/logs.css.scss deleted file mode 100644 index c8b22f9f5f..0000000000 --- a/services/api/app/assets/stylesheets/logs.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Logs controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/nodes.css b/services/api/app/assets/stylesheets/nodes.css deleted file mode 100644 index d1ce011576..0000000000 --- a/services/api/app/assets/stylesheets/nodes.css +++ /dev/null @@ -1,41 +0,0 @@ -/* Copyright (C) The Arvados Authors. All rights reserved. - -SPDX-License-Identifier: AGPL-3.0 */ - -/* - Place all the styles related to the matching controller here. - They will automatically be included in application.css. -*/ -.node-status { - /* unknown status - might be bad */ - background: #ff8888; -} -.node-status-running .node-status { - background: #88ff88; -} -.node-status-missing .node-status { - background: #ff8888; -} -.node-status-terminated .node-status { - background: #ffffff; -} - -.node-slurm-state { - /* unknown status - might be bad */ - background: #ff8888; -} -.node-status-missing .node-slurm-state { - background: #ffffff; -} -.node-status-terminated .node-slurm-state { - background: #ffffff; -} -.node-status-running .node-slurm-state-alloc { - background: #88ff88; -} -.node-status-running .node-slurm-state-idle { - background: #ffbbbb; -} -.node-status-running .node-slurm-state-down { - background: #ff8888; -} diff --git a/services/api/app/assets/stylesheets/nodes.css.scss b/services/api/app/assets/stylesheets/nodes.css.scss deleted file mode 100644 index a7b08612d7..0000000000 --- a/services/api/app/assets/stylesheets/nodes.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Nodes controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/pipeline_instances.css.scss b/services/api/app/assets/stylesheets/pipeline_instances.css.scss deleted file mode 100644 index 7292a9aa08..0000000000 --- a/services/api/app/assets/stylesheets/pipeline_instances.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the PipelineInstances controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/pipeline_templates.css.scss b/services/api/app/assets/stylesheets/pipeline_templates.css.scss deleted file mode 100644 index 40c0cefbea..0000000000 --- a/services/api/app/assets/stylesheets/pipeline_templates.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the PipelineTemplates controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/repositories.css.scss b/services/api/app/assets/stylesheets/repositories.css.scss deleted file mode 100644 index 1dd9a16603..0000000000 --- a/services/api/app/assets/stylesheets/repositories.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Repositories controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/specimens.css.scss b/services/api/app/assets/stylesheets/specimens.css.scss deleted file mode 100644 index 60d630c8ab..0000000000 --- a/services/api/app/assets/stylesheets/specimens.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Specimens controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/traits.css.scss b/services/api/app/assets/stylesheets/traits.css.scss deleted file mode 100644 index 7d2f7133e1..0000000000 --- a/services/api/app/assets/stylesheets/traits.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the Traits controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/assets/stylesheets/virtual_machines.css.scss b/services/api/app/assets/stylesheets/virtual_machines.css.scss deleted file mode 100644 index 4a94d45111..0000000000 --- a/services/api/app/assets/stylesheets/virtual_machines.css.scss +++ /dev/null @@ -1,7 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -// Place all the styles related to the VirtualMachines controller here. -// They will automatically be included in application.css. -// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/services/api/app/controllers/arvados/v1/collections_controller.rb b/services/api/app/controllers/arvados/v1/collections_controller.rb index ad1771a87e..155a8e8826 100644 --- a/services/api/app/controllers/arvados/v1/collections_controller.rb +++ b/services/api/app/controllers/arvados/v1/collections_controller.rb @@ -172,17 +172,7 @@ class Arvados::V1::CollectionsController < ApplicationController end if direction == :search_up - # Search upstream for jobs where this locator is the output of some job - if !Rails.configuration.API.DisabledAPIs["jobs.list"] - Job.readable_by(*@read_users).where(output: loc.to_s).each do |job| - search_edges(visited, job.uuid, :search_up) - end - - Job.readable_by(*@read_users).where(log: loc.to_s).each do |job| - search_edges(visited, job.uuid, :search_up) - end - end - + # Search upstream for jobs where this locator is the output of some container Container.readable_by(*@read_users).where(output: loc.to_s).pluck(:uuid).each do |c_uuid| search_edges(visited, c_uuid, :search_up) end @@ -196,17 +186,7 @@ class Arvados::V1::CollectionsController < ApplicationController return end - # Search downstream for jobs where this locator is in script_parameters - if !Rails.configuration.API.DisabledAPIs["jobs.list"] - Job.readable_by(*@read_users).where(["jobs.script_parameters like ?", "%#{loc.to_s}%"]).each do |job| - search_edges(visited, job.uuid, :search_down) - end - - Job.readable_by(*@read_users).where(["jobs.docker_image_locator = ?", "#{loc.to_s}"]).each do |job| - search_edges(visited, job.uuid, :search_down) - end - end - + # Search downstream for jobs where this locator is in mounts Container.readable_by(*@read_users).where([Container.full_text_trgm + " like ?", "%#{loc.to_s}%"]).select("output, log, uuid").each do |c| if c.output != loc.to_s && c.log != loc.to_s search_edges(visited, c.uuid, :search_down) @@ -216,21 +196,7 @@ class Arvados::V1::CollectionsController < ApplicationController else # uuid is a regular Arvados UUID rsc = ArvadosModel::resource_class_for_uuid uuid - if rsc == Job - Job.readable_by(*@read_users).where(uuid: uuid).each do |job| - visited[uuid] = job.as_api_response - if direction == :search_up - # Follow upstream collections referenced in the script parameters - find_collections(visited, job) do |hash, col_uuid| - search_edges(visited, hash, :search_up) if hash - search_edges(visited, col_uuid, :search_up) if col_uuid - end - elsif direction == :search_down - # Follow downstream job output - search_edges(visited, job.output, direction) - end - end - elsif rsc == Container + if rsc == Container c = Container.readable_by(*@read_users).where(uuid: uuid).limit(1).first if c visited[uuid] = c.as_api_response @@ -266,16 +232,6 @@ class Arvados::V1::CollectionsController < ApplicationController if direction == :search_up visited[c.uuid] = c.as_api_response - if !Rails.configuration.API.DisabledAPIs["jobs.list"] - Job.readable_by(*@read_users).where(output: c.portable_data_hash).each do |job| - search_edges(visited, job.uuid, :search_up) - end - - Job.readable_by(*@read_users).where(log: c.portable_data_hash).each do |job| - search_edges(visited, job.uuid, :search_up) - end - end - ContainerRequest.readable_by(*@read_users).where(output_uuid: uuid).pluck(:uuid).each do |cr_uuid| search_edges(visited, cr_uuid, :search_up) end diff --git a/services/api/app/controllers/arvados/v1/groups_controller.rb b/services/api/app/controllers/arvados/v1/groups_controller.rb index c362cf32d7..be73d39dd1 100644 --- a/services/api/app/controllers/arvados/v1/groups_controller.rb +++ b/services/api/app/controllers/arvados/v1/groups_controller.rb @@ -218,10 +218,7 @@ class Arvados::V1::GroupsController < ApplicationController request_filters = @filters - klasses = [Group, - Job, PipelineInstance, PipelineTemplate, ContainerRequest, Workflow, - Collection, - Human, Specimen, Trait] + klasses = [Group, ContainerRequest, Workflow, Collection] table_names = Hash[klasses.collect { |k| [k, k.table_name] }] diff --git a/services/api/app/controllers/arvados/v1/humans_controller.rb b/services/api/app/controllers/arvados/v1/humans_controller.rb deleted file mode 100644 index 88eee3058d..0000000000 --- a/services/api/app/controllers/arvados/v1/humans_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::HumansController < ApplicationController -end diff --git a/services/api/app/controllers/arvados/v1/job_tasks_controller.rb b/services/api/app/controllers/arvados/v1/job_tasks_controller.rb deleted file mode 100644 index b960d2e9e4..0000000000 --- a/services/api/app/controllers/arvados/v1/job_tasks_controller.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::JobTasksController < ApplicationController - accept_attribute_as_json :parameters, Hash - - def create - return send_error("Unsupported legacy jobs API", - status: 400) - end -end diff --git a/services/api/app/controllers/arvados/v1/jobs_controller.rb b/services/api/app/controllers/arvados/v1/jobs_controller.rb deleted file mode 100644 index 2d6b05269d..0000000000 --- a/services/api/app/controllers/arvados/v1/jobs_controller.rb +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::JobsController < ApplicationController - accept_attribute_as_json :components, Hash - accept_attribute_as_json :script_parameters, Hash - accept_attribute_as_json :runtime_constraints, Hash - accept_attribute_as_json :tasks_summary, Hash - skip_before_action :find_object_by_uuid, :only => [:queue, :queue_size] - skip_before_action :render_404_if_no_object, :only => [:queue, :queue_size] - - include DbCurrentTime - - def create - return send_error("Unsupported legacy jobs API", - status: 400) - end - - def cancel - return send_error("Unsupported legacy jobs API", - status: 400) - end - - def lock - return send_error("Unsupported legacy jobs API", - status: 400) - end - - def queue - @objects = [] - index - end - - def queue_size - render :json => {:queue_size => 0} - end - - def self._create_requires_parameters - (super rescue {}). - merge({ - find_or_create: { - type: 'boolean', required: false, default: false, - }, - filters: { - type: 'array', required: false, - }, - minimum_script_version: { - type: 'string', required: false, - }, - exclude_script_versions: { - type: 'array', required: false, - }, - }) - end - - def self._queue_requires_parameters - self._index_requires_parameters - end - - protected - - def load_filters_param - begin - super - attrs = resource_attrs rescue {} - @filters = Job.load_job_specific_filters attrs, @filters, @read_users - rescue ArgumentError => error - send_error(error.message) - false - else - true - end - end -end diff --git a/services/api/app/controllers/arvados/v1/keep_disks_controller.rb b/services/api/app/controllers/arvados/v1/keep_disks_controller.rb deleted file mode 100644 index b8aa09650f..0000000000 --- a/services/api/app/controllers/arvados/v1/keep_disks_controller.rb +++ /dev/null @@ -1,50 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::KeepDisksController < ApplicationController - skip_before_action :require_auth_scope, only: :ping - skip_before_action :render_404_if_no_object, only: :ping - - def self._ping_requires_parameters - { - uuid: {required: false}, - ping_secret: {required: true}, - node_uuid: {required: false}, - filesystem_uuid: {required: false}, - service_host: {required: false}, - service_port: {required: true}, - service_ssl_flag: {required: true} - } - end - - def ping - params[:service_host] ||= request.env['REMOTE_ADDR'] - if !params[:uuid] && current_user.andand.is_admin - # Create a new KeepDisk and ping it. - @object = KeepDisk.new(filesystem_uuid: params[:filesystem_uuid]) - @object.save! - - # In the first ping from this new filesystem_uuid, we can't - # expect the keep node to know the ping_secret so we made sure - # we got an admin token. Here we add ping_secret to params so - # the ping call below is properly authenticated. - params[:ping_secret] = @object.ping_secret - end - act_as_system_user do - if !@object.andand.ping(params) - return render_not_found "object not found" - end - # Render the :superuser view (i.e., include the ping_secret) even - # if !current_user.is_admin. This is safe because @object.ping's - # success implies the ping_secret was already known by the client. - send_json @object.as_api_response(:superuser) - end - end - - def find_objects_for_index - # all users can list all keep disks - @objects = model_class.where('1=1') - super - end -end diff --git a/services/api/app/controllers/arvados/v1/nodes_controller.rb b/services/api/app/controllers/arvados/v1/nodes_controller.rb deleted file mode 100644 index 2510fd49fa..0000000000 --- a/services/api/app/controllers/arvados/v1/nodes_controller.rb +++ /dev/null @@ -1,90 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::NodesController < ApplicationController - skip_before_action :require_auth_scope, :only => :ping - skip_before_action :find_object_by_uuid, :only => :ping - skip_before_action :render_404_if_no_object, :only => :ping - - include DbCurrentTime - - def self._ping_requires_parameters - { ping_secret: {required: true} } - end - - def self._create_requires_parameters - super.merge( - { assign_slot: {required: false, type: 'boolean', description: 'assign slot and hostname'} }) - end - - def self._update_requires_parameters - super.merge( - { assign_slot: {required: false, type: 'boolean', description: 'assign slot and hostname'} }) - end - - def create - @object = model_class.new(resource_attrs) - @object.assign_slot if params[:assign_slot] - @object.save! - show - end - - def update - if resource_attrs[:job_uuid].is_a? String - @object.job_readable = readable_job_uuids([resource_attrs[:job_uuid]]).any? - end - attrs_to_update = resource_attrs.reject { |k,v| - [:kind, :etag, :href].index k - } - @object.update!(attrs_to_update) - @object.assign_slot if params[:assign_slot] - @object.save! - show - end - - def ping - act_as_system_user do - @object = Node.where(uuid: (params[:id] || params[:uuid])).first - if !@object - return render_not_found - end - ping_data = { - ip: params[:local_ipv4] || request.remote_ip, - ec2_instance_id: params[:instance_id] - } - [:ping_secret, :total_cpu_cores, :total_ram_mb, :total_scratch_mb] - .each do |key| - ping_data[key] = params[key] if params[key] - end - @object.ping(ping_data) - if @object.info['ping_secret'] == params[:ping_secret] - send_json @object.as_api_response(:superuser) - else - raise "Invalid ping_secret after ping" - end - end - end - - def find_objects_for_index - if !current_user.andand.is_admin && current_user.andand.is_active - # active non-admin users can list nodes that are (or were - # recently) working - @objects = model_class.where('last_ping_at >= ?', db_current_time - 1.hours) - end - super - if @select.nil? or @select.include? 'job_uuid' - job_uuids = @objects.map { |n| n[:job_uuid] }.compact - assoc_jobs = readable_job_uuids(job_uuids) - @objects.each do |node| - node.job_readable = assoc_jobs.include?(node[:job_uuid]) - end - end - end - - protected - - def readable_job_uuids(uuids) - Job.readable_by(*@read_users).select(:uuid).where(uuid: uuids).map(&:uuid) - end -end diff --git a/services/api/app/controllers/arvados/v1/pipeline_instances_controller.rb b/services/api/app/controllers/arvados/v1/pipeline_instances_controller.rb deleted file mode 100644 index 166f71049b..0000000000 --- a/services/api/app/controllers/arvados/v1/pipeline_instances_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::PipelineInstancesController < ApplicationController - accept_attribute_as_json :components, Hash - accept_attribute_as_json :properties, Hash - accept_attribute_as_json :components_summary, Hash - - def create - return send_error("Unsupported legacy jobs API", - status: 400) - end - - def cancel - return send_error("Unsupported legacy jobs API", - status: 400) - end -end diff --git a/services/api/app/controllers/arvados/v1/pipeline_templates_controller.rb b/services/api/app/controllers/arvados/v1/pipeline_templates_controller.rb deleted file mode 100644 index 4a5e724ee6..0000000000 --- a/services/api/app/controllers/arvados/v1/pipeline_templates_controller.rb +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::PipelineTemplatesController < ApplicationController - accept_attribute_as_json :components, Hash - - def create - return send_error("Unsupported legacy jobs API", - status: 400) - end -end diff --git a/services/api/app/controllers/arvados/v1/repositories_controller.rb b/services/api/app/controllers/arvados/v1/repositories_controller.rb deleted file mode 100644 index 9dff6227bc..0000000000 --- a/services/api/app/controllers/arvados/v1/repositories_controller.rb +++ /dev/null @@ -1,124 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::RepositoriesController < ApplicationController - skip_before_action :find_object_by_uuid, :only => :get_all_permissions - skip_before_action :render_404_if_no_object, :only => :get_all_permissions - before_action :admin_required, :only => :get_all_permissions - - def get_all_permissions - # user_aks is a map of {user_uuid => array of public keys} - user_aks = {} - # admins is an array of user_uuids - admins = [] - User. - where('users.is_active = ? or users.uuid = ?', true, anonymous_user_uuid). - eager_load(:authorized_keys).find_each do |u| - user_aks[u.uuid] = u.authorized_keys.collect do |ak| - { - public_key: ak.public_key, - authorized_key_uuid: ak.uuid - } - end - admins << u.uuid if u.is_admin - end - all_group_permissions = User.all_group_permissions - @repo_info = {} - Repository.eager_load(:permissions).find_each do |repo| - @repo_info[repo.uuid] = { - uuid: repo.uuid, - name: repo.name, - push_url: repo.push_url, - fetch_url: repo.fetch_url, - user_permissions: {}, - } - # evidence is an array of {name: 'can_xxx', user_uuid: 'x-y-z'}, - # one entry for each piece of evidence we find in the permission - # database that establishes that a user can access this - # repository. Multiple entries can be added for a given user, - # possibly with different access levels; these will be compacted - # below. - evidence = [] - repo.permissions.each do |perm| - if ArvadosModel::resource_class_for_uuid(perm.tail_uuid) == Group - # A group has permission. Each user who has access to this - # group also has access to the repository. Access level is - # min(group-to-repo permission, user-to-group permission). - user_aks.each do |user_uuid, _| - perm_mask = all_group_permissions[user_uuid].andand[perm.tail_uuid] - if not perm_mask - next - elsif perm_mask[:manage] and perm.name == 'can_manage' - evidence << {name: 'can_manage', user_uuid: user_uuid} - elsif perm_mask[:write] and ['can_manage', 'can_write'].index perm.name - evidence << {name: 'can_write', user_uuid: user_uuid} - elsif perm_mask[:read] - evidence << {name: 'can_read', user_uuid: user_uuid} - end - end - elsif user_aks.has_key?(perm.tail_uuid) - # A user has permission; the user exists; and either the - # user is active, or it's the special case of the anonymous - # user which is never "active" but is allowed to read - # content from public repositories. - evidence << {name: perm.name, user_uuid: perm.tail_uuid} - end - end - # Owner of the repository, and all admins, can do everything. - ([repo.owner_uuid] | admins).each do |user_uuid| - # Except: no permissions for inactive users, even if they own - # repositories. - next unless user_aks.has_key?(user_uuid) - evidence << {name: 'can_manage', user_uuid: user_uuid} - end - # Distill all the evidence about permissions on this repository - # into one hash per user, of the form {'can_xxx' => true, ...}. - # The hash is nil for a user who has no permissions at all on - # this particular repository. - evidence.each do |perm| - user_uuid = perm[:user_uuid] - user_perms = (@repo_info[repo.uuid][:user_permissions][user_uuid] ||= {}) - user_perms[perm[:name]] = true - end - end - # Revisit each {'can_xxx' => true, ...} hash for some final - # cleanup to make life easier for the requestor. - # - # Add a 'gitolite_permissions' key alongside the 'can_xxx' keys, - # for the convenience of the gitolite config file generator. - # - # Add all lesser permissions when a greater permission is - # present. If the requestor only wants to know who can write, it - # only has to test for 'can_write' in the response. - @repo_info.values.each do |repo| - repo[:user_permissions].each do |user_uuid, user_perms| - if user_perms['can_manage'] - user_perms['gitolite_permissions'] = 'RW+' - user_perms['can_write'] = true - user_perms['can_read'] = true - elsif user_perms['can_write'] - user_perms['gitolite_permissions'] = 'RW+' - user_perms['can_read'] = true - elsif user_perms['can_read'] - user_perms['gitolite_permissions'] = 'R' - end - end - end - # The response looks like - # {"kind":"...", - # "repositories":[r1,r2,r3,...], - # "user_keys":usermap} - # where each of r1,r2,r3 looks like - # {"uuid":"repo-uuid-1", - # "name":"username/reponame", - # "push_url":"...", - # "user_permissions":{"user-uuid-a":{"can_read":true,"gitolite_permissions":"R"}}} - # and usermap looks like - # {"user-uuid-a":[{"public_key":"ssh-rsa g...","authorized_key_uuid":"ak-uuid-g"},...], - # "user-uuid-b":[{"public_key":"ssh-rsa h...","authorized_key_uuid":"ak-uuid-h"},...],...} - send_json(kind: 'arvados#RepositoryPermissionSnapshot', - repositories: @repo_info.values, - user_keys: user_aks) - end -end diff --git a/services/api/app/controllers/arvados/v1/schema_controller.rb b/services/api/app/controllers/arvados/v1/schema_controller.rb index 74aa4078cb..dd7a7a759e 100644 --- a/services/api/app/controllers/arvados/v1/schema_controller.rb +++ b/services/api/app/controllers/arvados/v1/schema_controller.rb @@ -57,13 +57,6 @@ class Arvados::V1::SchemaController < ApplicationController maxRequestSize: Rails.configuration.API.MaxRequestSize, maxItemsPerResponse: Rails.configuration.API.MaxItemsPerResponse, dockerImageFormats: Rails.configuration.Containers.SupportedDockerImageFormats.keys, - crunchLogBytesPerEvent: Rails.configuration.Containers.Logging.LogBytesPerEvent, - crunchLogSecondsBetweenEvents: Rails.configuration.Containers.Logging.LogSecondsBetweenEvents, - crunchLogThrottlePeriod: Rails.configuration.Containers.Logging.LogThrottlePeriod, - crunchLogThrottleBytes: Rails.configuration.Containers.Logging.LogThrottleBytes, - crunchLogThrottleLines: Rails.configuration.Containers.Logging.LogThrottleLines, - crunchLimitLogBytesPerJob: Rails.configuration.Containers.Logging.LimitLogBytesPerJob, - crunchLogPartialLineThrottlePeriod: Rails.configuration.Containers.Logging.LogPartialLineThrottlePeriod, crunchLogUpdatePeriod: Rails.configuration.Containers.Logging.LogUpdatePeriod, crunchLogUpdateSize: Rails.configuration.Containers.Logging.LogUpdateSize, remoteHosts: remoteHosts, @@ -72,7 +65,6 @@ class Arvados::V1::SchemaController < ApplicationController workbenchUrl: Rails.configuration.Services.Workbench1.ExternalURL.to_s, workbench2Url: Rails.configuration.Services.Workbench2.ExternalURL.to_s, keepWebServiceUrl: Rails.configuration.Services.WebDAV.ExternalURL.to_s, - gitUrl: Rails.configuration.Services.GitHTTP.ExternalURL.to_s, parameters: { alt: { type: "string", @@ -484,6 +476,7 @@ class Arvados::V1::SchemaController < ApplicationController Rails.configuration.API.DisabledAPIs.each do |method, _| ctrl, action = method.to_s.split('.', 2) + next if ctrl.in?(['job_tasks', 'jobs', 'keep_disks', 'nodes', 'pipeline_instances', 'pipeline_templates', 'repositories']) discovery[:resources][ctrl][:methods].delete(action.to_sym) end discovery diff --git a/services/api/app/controllers/arvados/v1/specimens_controller.rb b/services/api/app/controllers/arvados/v1/specimens_controller.rb deleted file mode 100644 index b1e50a7e3e..0000000000 --- a/services/api/app/controllers/arvados/v1/specimens_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::SpecimensController < ApplicationController -end diff --git a/services/api/app/controllers/arvados/v1/traits_controller.rb b/services/api/app/controllers/arvados/v1/traits_controller.rb deleted file mode 100644 index 7aaed5c4d4..0000000000 --- a/services/api/app/controllers/arvados/v1/traits_controller.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Arvados::V1::TraitsController < ApplicationController -end diff --git a/services/api/app/controllers/arvados/v1/users_controller.rb b/services/api/app/controllers/arvados/v1/users_controller.rb index 031dd2e4f9..418295d26a 100644 --- a/services/api/app/controllers/arvados/v1/users_controller.rb +++ b/services/api/app/controllers/arvados/v1/users_controller.rb @@ -123,8 +123,7 @@ class Arvados::V1::UsersController < ApplicationController full_repo_name = "#{@object.username}/#{params[:repo_name]}" end - @response = @object.setup(repo_name: full_repo_name, - vm_uuid: params[:vm_uuid], + @response = @object.setup(vm_uuid: params[:vm_uuid], send_notification_email: params[:send_notification_email]) send_json kind: "arvados#HashList", items: @response.as_api_response(nil) diff --git a/services/api/app/helpers/api_client_authorizations_helper.rb b/services/api/app/helpers/api_client_authorizations_helper.rb deleted file mode 100644 index e1066badc8..0000000000 --- a/services/api/app/helpers/api_client_authorizations_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -module ApiClientAuthorizationsHelper -end diff --git a/services/api/app/helpers/api_clients_helper.rb b/services/api/app/helpers/api_clients_helper.rb deleted file mode 100644 index 9604777598..0000000000 --- a/services/api/app/helpers/api_clients_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -module ApiClientsHelper -end diff --git a/services/api/app/helpers/authorized_keys_helper.rb b/services/api/app/helpers/authorized_keys_helper.rb deleted file mode 100644 index 665fff7f7c..0000000000 --- a/services/api/app/helpers/authorized_keys_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -module AuthorizedKeysHelper -end diff --git a/services/api/app/helpers/collections_helper.rb b/services/api/app/helpers/collections_helper.rb deleted file mode 100644 index ca44f474b9..0000000000 --- a/services/api/app/helpers/collections_helper.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -module CollectionsHelper -end diff --git a/services/api/app/helpers/commits_helper.rb b/services/api/app/helpers/commits_helper.rb deleted file mode 100644 index fdb83a0375..0000000000 --- a/services/api/app/helpers/commits_helper.rb +++ /dev/null @@ -1,270 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -module CommitsHelper - extend CurrentApiClient - - class GitError < RequestError - def http_status - 422 - end - end - - def self.git_check_ref_format(e) - if !e or e.empty? or e[0] == '-' or e[0] == '$' - # definitely not valid - false - else - `git check-ref-format --allow-onelevel #{e.shellescape}` - $?.success? - end - end - - # Return an array of commits (each a 40-char sha1) satisfying the - # given criteria. - # - # Return [] if the revisions given in minimum/maximum are invalid or - # don't exist in the given repository. - # - # Raise ArgumentError if the given repository is invalid, does not - # exist, or cannot be read for any reason. (Any transient error that - # prevents commit ranges from resolving must raise rather than - # returning an empty array.) - # - # repository can be the name of a locally hosted repository or a git - # URL (see git-fetch(1)). Currently http, https, and git schemes are - # supported. - def self.find_commit_range repository, minimum, maximum, exclude - if minimum and minimum.empty? - minimum = nil - end - - if minimum and !git_check_ref_format(minimum) - Rails.logger.warn "find_commit_range called with invalid minimum revision: '#{minimum}'" - return [] - end - - if maximum and !git_check_ref_format(maximum) - Rails.logger.warn "find_commit_range called with invalid maximum revision: '#{maximum}'" - return [] - end - - if !maximum - maximum = "HEAD" - end - - gitdir, is_remote = git_dir_for repository - fetch_remote_repository gitdir, repository if is_remote - ENV['GIT_DIR'] = gitdir - - commits = [] - - # Get the commit hash for the upper bound - max_hash = nil - git_max_hash_cmd = "git rev-list --max-count=1 #{maximum.shellescape} --" - IO.foreach("|#{git_max_hash_cmd}") do |line| - max_hash = line.strip - end - - # If not found, nothing else to do - if !max_hash - Rails.logger.warn "no refs found looking for max_hash: `GIT_DIR=#{gitdir} #{git_max_hash_cmd}` returned no output" - return [] - end - - # If string is invalid, nothing else to do - if !git_check_ref_format(max_hash) - Rails.logger.warn "ref returned by `GIT_DIR=#{gitdir} #{git_max_hash_cmd}` was invalid for max_hash: #{max_hash}" - return [] - end - - resolved_exclude = nil - if exclude - resolved_exclude = [] - exclude.each do |e| - if git_check_ref_format(e) - IO.foreach("|git rev-list --max-count=1 #{e.shellescape} --") do |line| - resolved_exclude.push(line.strip) - end - else - Rails.logger.warn "find_commit_range called with invalid exclude invalid characters: '#{exclude}'" - return [] - end - end - end - - if minimum - # Get the commit hash for the lower bound - min_hash = nil - git_min_hash_cmd = "git rev-list --max-count=1 #{minimum.shellescape} --" - IO.foreach("|#{git_min_hash_cmd}") do |line| - min_hash = line.strip - end - - # If not found, nothing else to do - if !min_hash - Rails.logger.warn "no refs found looking for min_hash: `GIT_DIR=#{gitdir} #{git_min_hash_cmd}` returned no output" - return [] - end - - # If string is invalid, nothing else to do - if !git_check_ref_format(min_hash) - Rails.logger.warn "ref returned by `GIT_DIR=#{gitdir} #{git_min_hash_cmd}` was invalid for min_hash: #{min_hash}" - return [] - end - - # Now find all commits between them - IO.foreach("|git rev-list #{min_hash.shellescape}..#{max_hash.shellescape} --") do |line| - hash = line.strip - commits.push(hash) if !resolved_exclude or !resolved_exclude.include? hash - end - - commits.push(min_hash) if !resolved_exclude or !resolved_exclude.include? min_hash - else - commits.push(max_hash) if !resolved_exclude or !resolved_exclude.include? max_hash - end - - commits - end - - # Given a repository (url, or name of hosted repo) and commit sha1, - # copy the commit into the internal git repo (if necessary), and tag - # it with the given tag (typically a job UUID). - # - # The repo can be a remote url, but in this case sha1 must already - # be present in our local cache for that repo: e.g., sha1 was just - # returned by find_commit_range. - def self.tag_in_internal_repository repo_name, sha1, tag - unless git_check_ref_format tag - raise ArgumentError.new "invalid tag #{tag}" - end - unless /^[0-9a-f]{40}$/ =~ sha1 - raise ArgumentError.new "invalid sha1 #{sha1}" - end - src_gitdir, _ = git_dir_for repo_name - unless src_gitdir - raise ArgumentError.new "no local repository for #{repo_name}" - end - dst_gitdir = Rails.configuration.Containers.JobsAPI.GitInternalDir - - begin - commit_in_dst = must_git(dst_gitdir, "log -n1 --format=%H #{sha1.shellescape}^{commit}").strip - rescue GitError - commit_in_dst = false - end - - tag_cmd = "tag --force #{tag.shellescape} #{sha1.shellescape}^{commit}" - if commit_in_dst == sha1 - must_git(dst_gitdir, tag_cmd) - else - # git-fetch is faster than pack-objects|unpack-objects, but - # git-fetch can't fetch by sha1. So we first try to fetch a - # branch that has the desired commit, and if that fails (there - # is no such branch, or the branch we choose changes under us in - # race), we fall back to pack|unpack. - begin - branches = must_git(src_gitdir, - "branch --contains #{sha1.shellescape}") - m = branches.match(/^. (\w+)\n/) - if !m - raise GitError.new "commit is not on any branch" - end - branch = m[1] - must_git(dst_gitdir, - "fetch file://#{src_gitdir.shellescape} #{branch.shellescape}") - # Even if all of the above steps succeeded, we might still not - # have the right commit due to a race, in which case tag_cmd - # will fail, and we'll need to fall back to pack|unpack. So - # don't be tempted to condense this tag_cmd and the one in the - # rescue block into a single attempt. - must_git(dst_gitdir, tag_cmd) - rescue GitError - must_pipe("echo #{sha1.shellescape}", - "git --git-dir #{src_gitdir.shellescape} pack-objects -q --revs --stdout", - "git --git-dir #{dst_gitdir.shellescape} unpack-objects -q") - must_git(dst_gitdir, tag_cmd) - end - end - end - - protected - - def self.remote_url? repo_name - /^(https?|git):\/\// =~ repo_name - end - - # Return [local_git_dir, is_remote]. If is_remote, caller must use - # fetch_remote_repository to ensure content is up-to-date. - # - # Raises an exception if the latest content could not be fetched for - # any reason. - def self.git_dir_for repo_name - if remote_url? repo_name - return [cache_dir_for(repo_name), true] - end - repos = Repository.readable_by(current_user).where(name: repo_name) - if repos.count == 0 - raise ArgumentError.new "Repository not found: '#{repo_name}'" - elsif repos.count > 1 - Rails.logger.error "Multiple repositories with name=='#{repo_name}'!" - raise ArgumentError.new "Name conflict" - else - return [repos.first.server_path, false] - end - end - - def self.cache_dir_for git_url - File.join(cache_dir_base, Digest::SHA1.hexdigest(git_url) + ".git").to_s - end - - def self.cache_dir_base - Rails.root.join 'tmp', 'git-cache' - end - - def self.fetch_remote_repository gitdir, git_url - # Caller decides which protocols are worth using. This is just a - # safety check to ensure we never use urls like "--flag" or wander - # into git's hardlink features by using bare "/path/foo" instead - # of "file:///path/foo". - unless /^[a-z]+:\/\// =~ git_url - raise ArgumentError.new "invalid git url #{git_url}" - end - begin - must_git gitdir, "branch" - rescue GitError => e - raise unless /Not a git repository/i =~ e.to_s - # OK, this just means we need to create a blank cache repository - # before fetching. - FileUtils.mkdir_p gitdir - must_git gitdir, "init" - end - must_git(gitdir, - "fetch --no-progress --tags --prune --force --update-head-ok #{git_url.shellescape} 'refs/heads/*:refs/heads/*'") - end - - def self.must_git gitdir, *cmds - # Clear token in case a git helper tries to use it as a password. - orig_token = ENV['ARVADOS_API_TOKEN'] - ENV['ARVADOS_API_TOKEN'] = '' - last_output = '' - begin - git = "git --git-dir #{gitdir.shellescape}" - cmds.each do |cmd| - last_output = must_pipe git+" "+cmd - end - ensure - ENV['ARVADOS_API_TOKEN'] = orig_token - end - return last_output - end - - def self.must_pipe *cmds - cmd = cmds.join(" 2>&1 |") + " 2>&1" - out = IO.read("| :new_record? @@ -73,6 +74,7 @@ class Container < ArvadosModel t.add :mounts t.add :output t.add :output_path + t.add :output_glob t.add :priority t.add :progress t.add :runtime_constraints @@ -164,6 +166,7 @@ class Container < ArvadosModel cwd: req.cwd, environment: req.environment, output_path: req.output_path, + output_glob: req.output_glob, container_image: resolve_container_image(req.container_image), mounts: resolve_mounts(req.mounts), runtime_constraints: resolve_runtime_constraints(req.runtime_constraints), @@ -263,6 +266,9 @@ class Container < ArvadosModel candidates = candidates.where('output_path = ?', attrs[:output_path]) log_reuse_info(candidates) { "after filtering on output_path #{attrs[:output_path].inspect}" } + candidates = candidates.where_serialized(:output_glob, attrs[:output_glob], md5: true) + log_reuse_info(candidates) { "after filtering on output_glob #{attrs[:output_glob].inspect}" } + image = resolve_container_image(attrs[:container_image]) candidates = candidates.where('container_image = ?', image) log_reuse_info(candidates) { "after filtering on container_image #{image.inspect} (resolved from #{attrs[:container_image].inspect})" } @@ -482,6 +488,7 @@ class Container < ArvadosModel self.environment ||= {} self.runtime_constraints ||= {} self.mounts ||= {} + self.output_glob ||= [] self.cwd ||= "." self.priority ||= 0 self.scheduling_parameters ||= {} @@ -531,11 +538,11 @@ class Container < ArvadosModel if self.new_record? permitted.push(:owner_uuid, :command, :container_image, :cwd, - :environment, :mounts, :output_path, :priority, - :runtime_constraints, :scheduling_parameters, - :secret_mounts, :runtime_token, - :runtime_user_uuid, :runtime_auth_scopes, - :output_storage_classes) + :environment, :mounts, :output_path, :output_glob, + :priority, :runtime_constraints, + :scheduling_parameters, :secret_mounts, + :runtime_token, :runtime_user_uuid, + :runtime_auth_scopes, :output_storage_classes) end case self.state @@ -798,6 +805,7 @@ class Container < ArvadosModel cwd: self.cwd, environment: self.environment, output_path: self.output_path, + output_glob: self.output_glob, container_image: self.container_image, mounts: self.mounts, runtime_constraints: self.runtime_constraints, diff --git a/services/api/app/models/container_request.rb b/services/api/app/models/container_request.rb index f5789f31f6..9b3d427594 100644 --- a/services/api/app/models/container_request.rb +++ b/services/api/app/models/container_request.rb @@ -34,6 +34,7 @@ class ContainerRequest < ArvadosModel serialize :runtime_constraints, Hash serialize :command, Array serialize :scheduling_parameters, Hash + serialize :output_glob, Array after_find :fill_container_defaults_after_find after_initialize { @state_was_when_initialized = self.state_was } # see finalize_if_needed @@ -73,6 +74,7 @@ class ContainerRequest < ArvadosModel t.add :name t.add :output_name t.add :output_path + t.add :output_glob t.add :output_uuid t.add :output_ttl t.add :priority @@ -104,7 +106,7 @@ class ContainerRequest < ArvadosModel AttrsPermittedAlways = [:owner_uuid, :state, :name, :description, :properties] AttrsPermittedBeforeCommit = [:command, :container_count_max, :container_image, :cwd, :environment, :filters, :mounts, - :output_path, :priority, :runtime_token, + :output_path, :output_glob, :priority, :runtime_token, :runtime_constraints, :state, :container_uuid, :use_existing, :scheduling_parameters, :secret_mounts, :output_name, :output_ttl, :output_storage_classes, :output_properties] @@ -307,7 +309,7 @@ class ContainerRequest < ArvadosModel end def self.full_text_searchable_columns - super - ["mounts", "secret_mounts", "secret_mounts_md5", "runtime_token", "output_storage_classes"] + super - ["mounts", "secret_mounts", "secret_mounts_md5", "runtime_token", "output_storage_classes", "output_glob"] end def set_priority_zero @@ -326,6 +328,7 @@ class ContainerRequest < ArvadosModel self.container_count_max ||= Rails.configuration.Containers.MaxRetryAttempts self.scheduling_parameters ||= {} self.output_ttl ||= 0 + self.output_glob ||= [] self.priority ||= 0 end @@ -442,6 +445,11 @@ class ContainerRequest < ArvadosModel errors.add(:environment, "must be an map of String to String but has entry #{k.class} to #{v.class}") end end + output_glob.each do |g| + if !g.is_a? String + errors.add(:output_glob, "must be an array of strings but has entry #{g.class}") + end + end [:mounts, :secret_mounts].each do |m| self[m].each do |k, v| if !k.is_a?(String) || !v.is_a?(Hash) diff --git a/services/api/app/models/human.rb b/services/api/app/models/human.rb deleted file mode 100644 index 68972825f9..0000000000 --- a/services/api/app/models/human.rb +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Human < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :properties, Hash - - api_accessible :user, extend: :common do |t| - t.add :properties - end -end diff --git a/services/api/app/models/job.rb b/services/api/app/models/job.rb deleted file mode 100644 index 029a313285..0000000000 --- a/services/api/app/models/job.rb +++ /dev/null @@ -1,564 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 -# -# -# Legacy jobs API aka crunch v1 -# -# This is superceded by containers / container_requests (aka crunch v2) -# -# Arvados installations since the end of 2017 should have never -# used jobs, and are unaffected by this change. -# -# So that older Arvados sites don't lose access to legacy records, the -# API has been converted to read-only. Creating and updating jobs -# (and related types job_task, pipeline_template and -# pipeline_instance) is disabled and much of the business logic -# related has been removed, along with the crunch-dispatch.rb and -# various other code specific to the jobs API. -# -# If you need to resurrect any of this code, here is the last commit -# on master before the branch removing jobs API support: -# -# Wed Aug 7 14:49:38 2019 -0400 07d92519438a592d531f2c7558cd51788da262ca - -require 'log_reuse_info' -require 'safe_json' - -class Job < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - extend CurrentApiClient - extend LogReuseInfo - serialize :components, Hash - serialize :script_parameters, Hash - serialize :runtime_constraints, Hash - serialize :tasks_summary, Hash - before_create :ensure_unique_submit_id - before_validation :set_priority - before_validation :update_state_from_old_state_attrs - before_validation :update_script_parameters_digest - validate :ensure_script_version_is_commit - validate :find_docker_image_locator - validate :find_arvados_sdk_version - validate :validate_status - validate :validate_state_change - validate :ensure_no_collection_uuids_in_script_params - before_save :tag_version_in_internal_repository - before_save :update_timestamps_when_state_changes - before_create :create_disabled - before_update :update_disabled - - has_many(:nodes, foreign_key: 'job_uuid', primary_key: 'uuid') - - class SubmitIdReused < RequestError - end - - api_accessible :user, extend: :common do |t| - t.add :submit_id - t.add :priority - t.add :script - t.add :script_parameters - t.add :script_version - t.add :cancelled_at - t.add :cancelled_by_client_uuid - t.add :cancelled_by_user_uuid - t.add :started_at - t.add :finished_at - t.add :output - t.add :success - t.add :running - t.add :state - t.add :is_locked_by_uuid - t.add :log - t.add :runtime_constraints - t.add :tasks_summary - t.add :nondeterministic - t.add :repository - t.add :supplied_script_version - t.add :arvados_sdk_version - t.add :docker_image_locator - t.add :queue_position - t.add :node_uuids - t.add :description - t.add :components - end - - # Supported states for a job - States = [ - (Queued = 'Queued'), - (Running = 'Running'), - (Cancelled = 'Cancelled'), - (Failed = 'Failed'), - (Complete = 'Complete'), - ] - - after_initialize do - @need_crunch_dispatch_trigger = false - end - - def self.limit_index_columns_read - ["components"] - end - - def self.protected_attributes - [:arvados_sdk_version, :docker_image_locator] - end - - def assert_finished - update(finished_at: finished_at || db_current_time, - success: success.nil? ? false : success, - running: false) - end - - def node_uuids - nodes.map(&:uuid) - end - - def self.queue - self.where('state = ?', Queued).order('priority desc, created_at') - end - - def queue_position - # We used to report this accurately, but the implementation made queue - # API requests O(n**2) for the size of the queue. See #8800. - # We've soft-disabled it because it's not clear we even want this - # functionality: now that we have Node Manager with support for multiple - # node sizes, "queue position" tells you very little about when a job will - # run. - state == Queued ? 0 : nil - end - - def self.running - self.where('running = ?', true). - order('priority desc, created_at') - end - - def lock locked_by_uuid - with_lock do - unless self.state == Queued and self.is_locked_by_uuid.nil? - raise AlreadyLockedError - end - self.state = Running - self.is_locked_by_uuid = locked_by_uuid - self.save! - end - end - - def update_script_parameters_digest - self.script_parameters_digest = self.class.sorted_hash_digest(script_parameters) - end - - def self.searchable_columns operator - super - ["script_parameters_digest"] - end - - def self.full_text_searchable_columns - super - ["script_parameters_digest"] - end - - def self.load_job_specific_filters attrs, orig_filters, read_users - # Convert Job-specific @filters entries into general SQL filters. - script_info = {"repository" => nil, "script" => nil} - git_filters = Hash.new do |hash, key| - hash[key] = {"max_version" => "HEAD", "exclude_versions" => []} - end - filters = [] - orig_filters.each do |attr, operator, operand| - if (script_info.has_key? attr) and (operator == "=") - if script_info[attr].nil? - script_info[attr] = operand - elsif script_info[attr] != operand - raise ArgumentError.new("incompatible #{attr} filters") - end - end - case operator - when "in git" - git_filters[attr]["min_version"] = operand - when "not in git" - git_filters[attr]["exclude_versions"] += Array.wrap(operand) - when "in docker", "not in docker" - image_hashes = Array.wrap(operand).flat_map do |search_term| - image_search, image_tag = search_term.split(':', 2) - Collection. - find_all_for_docker_image(image_search, image_tag, read_users, filter_compatible_format: false). - map(&:portable_data_hash) - end - filters << [attr, operator.sub(/ docker$/, ""), image_hashes] - else - filters << [attr, operator, operand] - end - end - - # Build a real script_version filter from any "not? in git" filters. - git_filters.each_pair do |attr, filter| - case attr - when "script_version" - script_info.each_pair do |key, value| - if value.nil? - raise ArgumentError.new("script_version filter needs #{key} filter") - end - end - filter["repository"] = script_info["repository"] - if attrs[:script_version] - filter["max_version"] = attrs[:script_version] - else - # Using HEAD, set earlier by the hash default, is fine. - end - when "arvados_sdk_version" - filter["repository"] = "arvados" - else - raise ArgumentError.new("unknown attribute for git filter: #{attr}") - end - revisions = CommitsHelper::find_commit_range(filter["repository"], - filter["min_version"], - filter["max_version"], - filter["exclude_versions"]) - if revisions.empty? - raise ArgumentError. - new("error searching #{filter['repository']} from " + - "'#{filter['min_version']}' to '#{filter['max_version']}', " + - "excluding #{filter['exclude_versions']}") - end - filters.append([attr, "in", revisions]) - end - - filters - end - - def self.default_git_filters(attr_name, repo_name, refspec) - # Add a filter to @filters for `attr_name` = the latest commit available - # in `repo_name` at `refspec`. No filter is added if refspec can't be - # resolved. - commits = CommitsHelper::find_commit_range(repo_name, nil, refspec, nil) - if commit_hash = commits.first - [[attr_name, "=", commit_hash]] - else - [] - end - end - - def cancel(cascade: false, need_transaction: true) - raise "No longer supported" - end - - protected - - def self.sorted_hash_digest h - Digest::MD5.hexdigest(Oj.dump(deep_sort_hash(h))) - end - - def foreign_key_attributes - super + %w(output log) - end - - def skip_uuid_read_permission_check - super + %w(cancelled_by_client_uuid) - end - - def skip_uuid_existence_check - super + %w(output log) - end - - def set_priority - if self.priority.nil? - self.priority = 0 - end - true - end - - def ensure_script_version_is_commit - if state == Running - # Apparently client has already decided to go for it. This is - # needed to run a local job using a local working directory - # instead of a commit-ish. - return true - end - if new_record? or repository_changed? or script_version_changed? - sha1 = CommitsHelper::find_commit_range(repository, - nil, script_version, nil).first - if not sha1 - errors.add :script_version, "#{script_version} does not resolve to a commit" - return false - end - if supplied_script_version.nil? or supplied_script_version.empty? - self.supplied_script_version = script_version - end - self.script_version = sha1 - end - true - end - - def tag_version_in_internal_repository - if state == Running - # No point now. See ensure_script_version_is_commit. - true - elsif errors.any? - # Won't be saved, and script_version might not even be valid. - true - elsif new_record? or repository_changed? or script_version_changed? - uuid_was = uuid - begin - assign_uuid - CommitsHelper::tag_in_internal_repository repository, script_version, uuid - rescue - self.uuid = uuid_was - raise - end - end - end - - def ensure_unique_submit_id - if !submit_id.nil? - if Job.where('submit_id=?',self.submit_id).first - raise SubmitIdReused.new - end - end - true - end - - def resolve_runtime_constraint(key, attr_sym) - if ((runtime_constraints.is_a? Hash) and - (search = runtime_constraints[key])) - ok, result = yield search - else - ok, result = true, nil - end - if ok - send("#{attr_sym}=".to_sym, result) - else - errors.add(attr_sym, result) - end - ok - end - - def find_arvados_sdk_version - resolve_runtime_constraint("arvados_sdk_version", - :arvados_sdk_version) do |git_search| - commits = CommitsHelper::find_commit_range("arvados", - nil, git_search, nil) - if commits.empty? - [false, "#{git_search} does not resolve to a commit"] - elsif not runtime_constraints["docker_image"] - [false, "cannot be specified without a Docker image constraint"] - else - [true, commits.first] - end - end - end - - def find_docker_image_locator - if runtime_constraints.is_a? Hash and Rails.configuration.Containers.JobsAPI.DefaultDockerImage != "" - runtime_constraints['docker_image'] ||= - Rails.configuration.Containers.JobsAPI.DefaultDockerImage - end - - resolve_runtime_constraint("docker_image", - :docker_image_locator) do |image_search| - image_tag = runtime_constraints['docker_image_tag'] - if coll = Collection.for_latest_docker_image(image_search, image_tag) - [true, coll.portable_data_hash] - else - [false, "not found for #{image_search}"] - end - end - end - - def permission_to_update - if is_locked_by_uuid_was and !(current_user and - (current_user.uuid == is_locked_by_uuid_was or - current_user.uuid == system_user.uuid)) - if script_changed? or - script_parameters_changed? or - script_version_changed? or - (!cancelled_at_was.nil? and - (cancelled_by_client_uuid_changed? or - cancelled_by_user_uuid_changed? or - cancelled_at_changed?)) or - started_at_changed? or - finished_at_changed? or - running_changed? or - success_changed? or - output_changed? or - log_changed? or - tasks_summary_changed? or - (state_changed? && state != Cancelled) or - components_changed? - logger.warn "User #{current_user.uuid if current_user} tried to change protected job attributes on locked #{self.class.to_s} #{uuid_was}" - return false - end - end - if !is_locked_by_uuid_changed? - super - else - if !current_user - logger.warn "Anonymous user tried to change lock on #{self.class.to_s} #{uuid_was}" - false - elsif is_locked_by_uuid_was and is_locked_by_uuid_was != current_user.uuid - logger.warn "User #{current_user.uuid} tried to steal lock on #{self.class.to_s} #{uuid_was} from #{is_locked_by_uuid_was}" - false - elsif !is_locked_by_uuid.nil? and is_locked_by_uuid != current_user.uuid - logger.warn "User #{current_user.uuid} tried to lock #{self.class.to_s} #{uuid_was} with uuid #{is_locked_by_uuid}" - false - else - super - end - end - end - - def update_modified_by_fields - if self.cancelled_at_changed? - # Ensure cancelled_at cannot be set to arbitrary non-now times, - # or changed once it is set. - if self.cancelled_at and not self.cancelled_at_was - self.cancelled_at = db_current_time - self.cancelled_by_user_uuid = current_user.uuid - self.cancelled_by_client_uuid = current_api_client.andand.uuid - @need_crunch_dispatch_trigger = true - else - self.cancelled_at = self.cancelled_at_was - self.cancelled_by_user_uuid = self.cancelled_by_user_uuid_was - self.cancelled_by_client_uuid = self.cancelled_by_client_uuid_was - end - end - super - end - - def update_timestamps_when_state_changes - return if not (state_changed? or new_record?) - - case state - when Running - self.started_at ||= db_current_time - when Failed, Complete - self.finished_at ||= db_current_time - when Cancelled - self.cancelled_at ||= db_current_time - end - - # TODO: Remove the following case block when old "success" and - # "running" attrs go away. Until then, this ensures we still - # expose correct success/running flags to older clients, even if - # some new clients are writing only the new state attribute. - case state - when Queued - self.running = false - self.success = nil - when Running - self.running = true - self.success = nil - when Cancelled, Failed - self.running = false - self.success = false - when Complete - self.running = false - self.success = true - end - self.running ||= false # Default to false instead of nil. - - @need_crunch_dispatch_trigger = true - - true - end - - def update_state_from_old_state_attrs - # If a client has touched the legacy state attrs, update the - # "state" attr to agree with the updated values of the legacy - # attrs. - # - # TODO: Remove this method when old "success" and "running" attrs - # go away. - if cancelled_at_changed? or - success_changed? or - running_changed? or - state.nil? - if cancelled_at - self.state = Cancelled - elsif success == false - self.state = Failed - elsif success == true - self.state = Complete - elsif running == true - self.state = Running - else - self.state = Queued - end - end - true - end - - def validate_status - if self.state.in?(States) - true - else - errors.add :state, "#{state.inspect} must be one of: #{States.inspect}" - false - end - end - - def validate_state_change - ok = true - if self.state_changed? - ok = case self.state_was - when nil - # state isn't set yet - true - when Queued - # Permit going from queued to any state - true - when Running - # From running, may only transition to a finished state - [Complete, Failed, Cancelled].include? self.state - when Complete, Failed, Cancelled - # Once in a finished state, don't permit any more state changes - false - else - # Any other state transition is also invalid - false - end - if not ok - errors.add :state, "invalid change from #{self.state_was} to #{self.state}" - end - end - ok - end - - def ensure_no_collection_uuids_in_script_params - # Fail validation if any script_parameters field includes a string containing a - # collection uuid pattern. - if self.script_parameters_changed? - if recursive_hash_search(self.script_parameters, Collection.uuid_regex) - self.errors.add :script_parameters, "must use portable_data_hash instead of collection uuid" - return false - end - end - true - end - - # recursive_hash_search searches recursively through hashes and - # arrays in 'thing' for string fields matching regular expression - # 'pattern'. Returns true if pattern is found, false otherwise. - def recursive_hash_search thing, pattern - if thing.is_a? Hash - thing.each do |k, v| - return true if recursive_hash_search v, pattern - end - elsif thing.is_a? Array - thing.each do |k| - return true if recursive_hash_search k, pattern - end - elsif thing.is_a? String - return true if thing.match pattern - end - false - end - - def create_disabled - raise "Disabled" - end - - def update_disabled - raise "Disabled" - end -end diff --git a/services/api/app/models/job_task.rb b/services/api/app/models/job_task.rb deleted file mode 100644 index b181e76ccf..0000000000 --- a/services/api/app/models/job_task.rb +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class JobTask < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :parameters, Hash - before_create :set_default_qsequence - after_update :delete_created_job_tasks_if_failed - before_create :create_disabled - before_update :update_disabled - - api_accessible :user, extend: :common do |t| - t.add :job_uuid - t.add :created_by_job_task_uuid - t.add :sequence - t.add :qsequence - t.add :parameters - t.add :output - t.add :progress - t.add :success - t.add :started_at - t.add :finished_at - end - - protected - - def delete_created_job_tasks_if_failed - if self.success == false and self.success != self.success_was - JobTask.delete_all ['created_by_job_task_uuid = ?', self.uuid] - end - end - - def set_default_qsequence - self.qsequence ||= self.class.connection. - select_value("SELECT nextval('job_tasks_qsequence_seq')") - end - - def create_disabled - raise "Disabled" - end - - def update_disabled - raise "Disabled" - end -end diff --git a/services/api/app/models/keep_disk.rb b/services/api/app/models/keep_disk.rb deleted file mode 100644 index 589936f845..0000000000 --- a/services/api/app/models/keep_disk.rb +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class KeepDisk < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - before_validation :ensure_ping_secret - - api_accessible :user, extend: :common do |t| - t.add :node_uuid - t.add :filesystem_uuid - t.add :bytes_total - t.add :bytes_free - t.add :is_readable - t.add :is_writable - t.add :last_read_at - t.add :last_write_at - t.add :last_ping_at - t.add :service_host - t.add :service_port - t.add :service_ssl_flag - t.add :keep_service_uuid - end - api_accessible :superuser, :extend => :user do |t| - t.add :ping_secret - end - - def foreign_key_attributes - super.reject { |a| a == "filesystem_uuid" } - end - - def ping(o) - raise "must have :service_host and :ping_secret" unless o[:service_host] and o[:ping_secret] - - if o[:ping_secret] != self.ping_secret - logger.info "Ping: secret mismatch: received \"#{o[:ping_secret]}\" != \"#{self.ping_secret}\"" - return nil - end - - @bypass_arvados_authorization = true - self.update!(o.select { |k,v| - [:bytes_total, - :bytes_free, - :is_readable, - :is_writable, - :last_read_at, - :last_write_at - ].collect(&:to_s).index k - }.merge(last_ping_at: db_current_time)) - end - - def service_host - KeepService.find_by_uuid(self.keep_service_uuid).andand.service_host - end - - def service_port - KeepService.find_by_uuid(self.keep_service_uuid).andand.service_port - end - - def service_ssl_flag - KeepService.find_by_uuid(self.keep_service_uuid).andand.service_ssl_flag - end - - protected - - def ensure_ping_secret - self.ping_secret ||= rand(2**256).to_s(36) - end - - def permission_to_update - @bypass_arvados_authorization or super - end - - def permission_to_create - current_user and current_user.is_admin - end -end diff --git a/services/api/app/models/node.rb b/services/api/app/models/node.rb deleted file mode 100644 index f384ba582b..0000000000 --- a/services/api/app/models/node.rb +++ /dev/null @@ -1,295 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'tempfile' - -class Node < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - - # Posgresql JSONB columns should NOT be declared as serialized, Rails 5 - # already know how to properly treat them. - attribute :properties, :jsonbHash, default: {} - attribute :info, :jsonbHash, default: {} - - before_validation :ensure_ping_secret - after_update :dns_server_update - - # Only a controller can figure out whether or not the current API tokens - # have access to the associated Job. They're expected to set - # job_readable=true if the Job UUID can be included in the API response. - belongs_to :job, - foreign_key: 'job_uuid', - primary_key: 'uuid', - optional: true - attr_accessor :job_readable - - UNUSED_NODE_IP = '127.40.4.0' - MAX_VMS = 3 - - api_accessible :user, :extend => :common do |t| - t.add :hostname - t.add :domain - t.add :ip_address - t.add :last_ping_at - t.add :slot_number - t.add :status - t.add :api_job_uuid, as: :job_uuid - t.add :crunch_worker_state - t.add :properties - end - api_accessible :superuser, :extend => :user do |t| - t.add :first_ping_at - t.add :info - t.add lambda { |x| Rails.configuration.Containers.SLURM.Managed.ComputeNodeNameservers.keys }, :as => :nameservers - end - - after_initialize do - @bypass_arvados_authorization = false - end - - def domain - super || Rails.configuration.Containers.SLURM.Managed.ComputeNodeDomain - end - - def api_job_uuid - job_readable ? job_uuid : nil - end - - def crunch_worker_state - return 'down' if slot_number.nil? - case self.info.andand['slurm_state'] - when 'alloc', 'comp', 'mix', 'drng' - 'busy' - when 'idle' - 'idle' - else - 'down' - end - end - - def status - if !self.last_ping_at - if db_current_time - self.created_at > 5.minutes - 'startup-fail' - else - 'pending' - end - elsif db_current_time - self.last_ping_at > 1.hours - 'missing' - else - 'running' - end - end - - def ping(o) - raise "must have :ip and :ping_secret" unless o[:ip] and o[:ping_secret] - - if o[:ping_secret] != self.info['ping_secret'] - logger.info "Ping: secret mismatch: received \"#{o[:ping_secret]}\" != \"#{self.info['ping_secret']}\"" - raise ArvadosModel::UnauthorizedError.new("Incorrect ping_secret") - end - - current_time = db_current_time - self.last_ping_at = current_time - - @bypass_arvados_authorization = true - - # Record IP address - if self.ip_address.nil? - logger.info "#{self.uuid} ip_address= #{o[:ip]}" - self.ip_address = o[:ip] - self.first_ping_at = current_time - end - - # Record instance ID if not already known - if o[:ec2_instance_id] - if !self.info['ec2_instance_id'] - self.info['ec2_instance_id'] = o[:ec2_instance_id] - elsif self.info['ec2_instance_id'] != o[:ec2_instance_id] - logger.debug "Multiple nodes have credentials for #{self.uuid}" - raise "#{self.uuid} is already running at #{self.info['ec2_instance_id']} so rejecting ping from #{o[:ec2_instance_id]}" - end - end - - assign_slot - - # Record other basic stats - ['total_cpu_cores', 'total_ram_mb', 'total_scratch_mb'].each do |key| - if value = (o[key] or o[key.to_sym]) - self.properties[key] = value.to_i - else - self.properties.delete(key) - end - end - - save! - end - - def assign_slot - return if self.slot_number.andand > 0 - while true - self.slot_number = self.class.available_slot_number - if self.slot_number.nil? - raise "No available node slots" - end - begin - save! - return assign_hostname - rescue ActiveRecord::RecordNotUnique - # try again - end - end - end - - protected - - def assign_hostname - if self.hostname.nil? and Rails.configuration.Containers.SLURM.Managed.AssignNodeHostname - self.hostname = self.class.hostname_for_slot(self.slot_number) - end - end - - def self.available_slot_number - # Join the sequence 1..max with the nodes table. Return the first - # (i.e., smallest) value that doesn't match the slot_number of any - # existing node. - connection.exec_query('SELECT n FROM generate_series(1, $1) AS slot(n) - LEFT JOIN nodes ON n=slot_number - WHERE slot_number IS NULL - LIMIT 1', - # query label: - 'Node.available_slot_number', - # bind vars: - [MAX_VMS], - ).rows.first.andand.first - end - - def ensure_ping_secret - self.info['ping_secret'] ||= rand(2**256).to_s(36) - end - - def dns_server_update - if saved_change_to_ip_address? && ip_address - Node.where('id != ? and ip_address = ?', - id, ip_address).each do |stale_node| - # One or more(!) stale node records have the same IP address - # as the new node. Clear the ip_address field on the stale - # nodes. Otherwise, we (via SLURM) might inadvertently connect - # to the new node using the old node's hostname. - stale_node.update!(ip_address: nil) - end - end - if hostname_before_last_save && saved_change_to_hostname? - self.class.dns_server_update(hostname_before_last_save, UNUSED_NODE_IP) - end - if hostname && (saved_change_to_hostname? || saved_change_to_ip_address?) - self.class.dns_server_update(hostname, ip_address || UNUSED_NODE_IP) - end - end - - def self.dns_server_update hostname, ip_address - ok = true - - ptr_domain = ip_address. - split('.').reverse.join('.').concat('.in-addr.arpa') - - template_vars = { - hostname: hostname, - uuid_prefix: Rails.configuration.ClusterID, - ip_address: ip_address, - ptr_domain: ptr_domain, - } - - if (!Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir.to_s.empty? and - !Rails.configuration.Containers.SLURM.Managed.DNSServerConfTemplate.to_s.empty?) - tmpfile = nil - begin - begin - template = IO.read(Rails.configuration.Containers.SLURM.Managed.DNSServerConfTemplate) - rescue IOError, SystemCallError => e - logger.error "Reading #{Rails.configuration.Containers.SLURM.Managed.DNSServerConfTemplate}: #{e.message}" - raise - end - - hostfile = File.join Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir, "#{hostname}.conf" - Tempfile.open(["#{hostname}-", ".conf.tmp"], - Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir) do |f| - tmpfile = f.path - f.puts template % template_vars - end - File.rename tmpfile, hostfile - rescue IOError, SystemCallError => e - logger.error "Writing #{hostfile}: #{e.message}" - ok = false - ensure - if tmpfile and File.file? tmpfile - # Cleanup remaining temporary file. - File.unlink tmpfile - end - end - end - - if !Rails.configuration.Containers.SLURM.Managed.DNSServerUpdateCommand.empty? - cmd = Rails.configuration.Containers.SLURM.Managed.DNSServerUpdateCommand % template_vars - if not system cmd - logger.error "dns_server_update_command #{cmd.inspect} failed: #{$?}" - ok = false - end - end - - if (!Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir.to_s.empty? and - !Rails.configuration.Containers.SLURM.Managed.DNSServerReloadCommand.to_s.empty?) - restartfile = File.join(Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir, 'restart.txt') - begin - File.open(restartfile, 'w') do |f| - # Typically, this is used to trigger a dns server restart - f.puts Rails.configuration.Containers.SLURM.Managed.DNSServerReloadCommand - end - rescue IOError, SystemCallError => e - logger.error "Unable to write #{restartfile}: #{e.message}" - ok = false - end - end - - ok - end - - def self.hostname_for_slot(slot_number) - config = Rails.configuration.Containers.SLURM.Managed.AssignNodeHostname - - return nil if !config - - sprintf(config, {:slot_number => slot_number}) - end - - # At startup, make sure all DNS entries exist. Otherwise, slurmctld - # will refuse to start. - if (!Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir.to_s.empty? and - !Rails.configuration.Containers.SLURM.Managed.DNSServerConfTemplate.to_s.empty? and - !Rails.configuration.Containers.SLURM.Managed.AssignNodeHostname.empty?) - - (0..MAX_VMS-1).each do |slot_number| - hostname = hostname_for_slot(slot_number) - hostfile = File.join Rails.configuration.Containers.SLURM.Managed.DNSServerConfDir, "#{hostname}.conf" - if !File.exist? hostfile - n = Node.where(:slot_number => slot_number).first - if n.nil? or n.ip_address.nil? - dns_server_update(hostname, UNUSED_NODE_IP) - else - dns_server_update(hostname, n.ip_address) - end - end - end - end - - def permission_to_update - @bypass_arvados_authorization or super - end - - def permission_to_create - current_user and current_user.is_admin - end -end diff --git a/services/api/app/models/pipeline_instance.rb b/services/api/app/models/pipeline_instance.rb deleted file mode 100644 index 0b0af8b87d..0000000000 --- a/services/api/app/models/pipeline_instance.rb +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class PipelineInstance < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :components, Hash - serialize :properties, Hash - serialize :components_summary, Hash - belongs_to :pipeline_template, - foreign_key: 'pipeline_template_uuid', - primary_key: 'uuid', - optional: true - - before_validation :bootstrap_components - before_validation :update_state - before_validation :verify_status - before_validation :update_timestamps_when_state_changes - before_create :set_state_before_save - before_save :set_state_before_save - before_create :create_disabled - before_update :update_disabled - - api_accessible :user, extend: :common do |t| - t.add :pipeline_template_uuid - t.add :name - t.add :components - t.add :properties - t.add :state - t.add :components_summary - t.add :description - t.add :started_at - t.add :finished_at - end - - # Supported states for a pipeline instance - States = - [ - (New = 'New'), - (Ready = 'Ready'), - (RunningOnServer = 'RunningOnServer'), - (RunningOnClient = 'RunningOnClient'), - (Paused = 'Paused'), - (Failed = 'Failed'), - (Complete = 'Complete'), - ] - - def self.limit_index_columns_read - ["components"] - end - - # if all components have input, the pipeline is Ready - def components_look_ready? - if !self.components || self.components.empty? - return false - end - - all_components_have_input = true - self.components.each do |name, component| - component['script_parameters'].andand.each do |parametername, parameter| - parameter = { 'value' => parameter } unless parameter.is_a? Hash - if parameter['value'].nil? and parameter['required'] - if parameter['output_of'] - next - end - all_components_have_input = false - break - end - end - end - return all_components_have_input - end - - def progress_table - begin - # v0 pipeline format - nrow = -1 - components['steps'].collect do |step| - nrow += 1 - row = [nrow, step['name']] - if step['complete'] and step['complete'] != 0 - if step['output_data_locator'] - row << 1.0 - else - row << 0.0 - end - else - row << 0.0 - if step['failed'] - self.state = Failed - end - end - row << (step['warehousejob']['id'] rescue nil) - row << (step['warehousejob']['revision'] rescue nil) - row << step['output_data_locator'] - row << (Time.parse(step['warehousejob']['finishtime']) rescue nil) - row - end - rescue - [] - end - end - - def progress_ratio - t = progress_table - return 0 if t.size < 1 - t.collect { |r| r[2] }.inject(0.0) { |sum,a| sum += a } / t.size - end - - def self.queue - self.where("state = 'RunningOnServer'") - end - - def cancel(cascade: false, need_transaction: true) - raise "No longer supported" - end - - protected - def bootstrap_components - if pipeline_template and (!components or components.empty?) - self.components = pipeline_template.components.deep_dup - end - end - - def update_state - if components and progress_ratio == 1.0 - self.state = Complete - end - end - - def verify_status - changed_attributes = self.changed - - if new_record? or 'components'.in? changed_attributes - self.state ||= New - if (self.state == New) and self.components_look_ready? - self.state = Ready - end - end - - if !self.state.in?(States) - errors.add :state, "'#{state.inspect} must be one of: [#{States.join ', '}]" - throw(:abort) - end - end - - def set_state_before_save - if self.components_look_ready? && (!self.state || self.state == New) - self.state = Ready - end - end - - def update_timestamps_when_state_changes - return if not (state_changed? or new_record?) - - case state - when RunningOnServer, RunningOnClient - self.started_at ||= db_current_time - when Failed, Complete - current_time = db_current_time - self.started_at ||= current_time - self.finished_at ||= current_time - end - end - - - def create_disabled - raise "Disabled" - end - - def update_disabled - raise "Disabled" - end -end diff --git a/services/api/app/models/pipeline_template.rb b/services/api/app/models/pipeline_template.rb deleted file mode 100644 index 7c694698e0..0000000000 --- a/services/api/app/models/pipeline_template.rb +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class PipelineTemplate < ArvadosModel - before_create :create_disabled - before_update :update_disabled - - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :components, Hash - - api_accessible :user, extend: :common do |t| - t.add :name - t.add :components - t.add :description - end - - def self.limit_index_columns_read - ["components"] - end - - def create_disabled - raise "Disabled" - end - - def update_disabled - raise "Disabled" - end -end diff --git a/services/api/app/models/repository.rb b/services/api/app/models/repository.rb deleted file mode 100644 index 46f2de6ee4..0000000000 --- a/services/api/app/models/repository.rb +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Repository < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - - # Order is important here. We must validate the owner before we can - # validate the name. - validate :valid_owner - validate :name_format, :if => Proc.new { |r| r.errors[:owner_uuid].empty? } - validates(:name, uniqueness: true, allow_nil: false) - - api_accessible :user, extend: :common do |t| - t.add :name - t.add :fetch_url - t.add :push_url - t.add :clone_urls - end - - def self.attributes_required_columns - super.merge("clone_urls" => ["name"], - "fetch_url" => ["name"], - "push_url" => ["name"]) - end - - # Deprecated. Use clone_urls instead. - def push_url - ssh_clone_url - end - - # Deprecated. Use clone_urls instead. - def fetch_url - ssh_clone_url - end - - def clone_urls - [ssh_clone_url, https_clone_url].compact - end - - def server_path - # Find where the repository is stored on the API server's filesystem, - # and return that path, or nil if not found. - # This method is only for the API server's internal use, and should not - # be exposed through the public API. Following our current gitolite - # setup, it searches for repositories stored by UUID, then name; and it - # prefers bare repositories over checkouts. - [["%s.git"], ["%s", ".git"]].each do |repo_base, *join_args| - [:uuid, :name].each do |path_attr| - git_dir = File.join(Rails.configuration.Git.Repositories, - repo_base % send(path_attr), *join_args) - return git_dir if File.exist?(git_dir) - end - end - nil - end - - protected - - def permission_to_update - if not super - false - elsif current_user.is_admin - true - elsif name_changed? - current_user.uuid == owner_uuid - else - true - end - end - - def owner - User.find_by_uuid(owner_uuid) - end - - def valid_owner - if owner.nil? or (owner.username.nil? and (owner.uuid != system_user_uuid)) - errors.add(:owner_uuid, "must refer to a user with a username") - false - end - end - - def name_format - if owner.uuid == system_user_uuid - prefix_match = "" - errmsg_start = "must be" - else - prefix_match = Regexp.escape(owner.username + "/") - errmsg_start = "must be the owner's username, then '/', then" - end - if not (/^#{prefix_match}[A-Za-z][A-Za-z0-9]*$/.match(name)) - errors.add(:name, - "#{errmsg_start} a letter followed by alphanumerics, expected pattern '#{prefix_match}[A-Za-z][A-Za-z0-9]*' but was '#{name}'") - false - end - end - - def ssh_clone_url - _clone_url Rails.configuration.Services.GitSSH.andand.ExternalURL, 'ssh://git@git.%s.arvadosapi.com' - end - - def https_clone_url - _clone_url Rails.configuration.Services.GitHTTP.andand.ExternalURL, 'https://git.%s.arvadosapi.com/' - end - - def _clone_url config_var, default_base_fmt - if not config_var - return "" - end - prefix = new_record? ? Rails.configuration.ClusterID : uuid[0,5] - if prefix == Rails.configuration.ClusterID and config_var != URI("") - base = config_var - else - base = URI(default_base_fmt % prefix) - end - if base.path == "" - base.path = "/" - end - if base.scheme == "ssh" - '%s@%s:%s.git' % [base.user, base.host, name] - else - '%s%s.git' % [base, name] - end - end -end diff --git a/services/api/app/models/specimen.rb b/services/api/app/models/specimen.rb deleted file mode 100644 index 32d5ed57f3..0000000000 --- a/services/api/app/models/specimen.rb +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Specimen < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :properties, Hash - - api_accessible :user, extend: :common do |t| - t.add :material - t.add :properties - end - - def properties - @properties ||= Hash.new - super - end -end diff --git a/services/api/app/models/trait.rb b/services/api/app/models/trait.rb deleted file mode 100644 index 2d3556b51d..0000000000 --- a/services/api/app/models/trait.rb +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -class Trait < ArvadosModel - include HasUuid - include KindAndEtag - include CommonApiTemplate - serialize :properties, Hash - - api_accessible :user, extend: :common do |t| - t.add :name - t.add :properties - end -end diff --git a/services/api/app/models/user.rb b/services/api/app/models/user.rb index 5a95fb0b88..c104ac6fda 100644 --- a/services/api/app/models/user.rb +++ b/services/api/app/models/user.rb @@ -25,9 +25,6 @@ class User < ArvadosModel before_update :prevent_privilege_escalation before_update :prevent_inactive_admin before_update :prevent_nonadmin_system_root - before_update :verify_repositories_empty, :if => Proc.new { - username.nil? and username_changed? - } after_update :setup_on_activate before_create :check_auto_admin @@ -49,16 +46,10 @@ class User < ArvadosModel before_update :before_ownership_change after_update :after_ownership_change after_update :send_profile_created_notification - after_update :sync_repository_names, :if => Proc.new { - (uuid != system_user_uuid) and - saved_change_to_username? and - (not username_before_last_save.nil?) - } before_destroy :clear_permissions after_destroy :remove_self_from_permissions has_many :authorized_keys, foreign_key: 'authorized_user_uuid', primary_key: 'uuid' - has_many :repositories, foreign_key: 'owner_uuid', primary_key: 'uuid' default_scope { where('redirect_to_user_uuid is null') } @@ -261,7 +252,7 @@ SELECT target_uuid, perm_level end # create links - def setup(repo_name: nil, vm_uuid: nil, send_notification_email: nil) + def setup(vm_uuid: nil, send_notification_email: nil) newly_invited = Link.where(tail_uuid: self.uuid, head_uuid: all_users_group_uuid, link_class: 'permission').empty? @@ -271,12 +262,6 @@ SELECT target_uuid, perm_level # direction which makes this user visible to other users. group_perms = add_to_all_users_group - # Add git repo - repo_perm = if (!repo_name.nil? || Rails.configuration.Users.AutoSetupNewUsersWithRepository) and !username.nil? - repo_name ||= "#{username}/#{username}" - create_user_repo_link repo_name - end - # Add virtual machine if vm_uuid.nil? and !Rails.configuration.Users.AutoSetupNewUsersWithVmUUID.empty? vm_uuid = Rails.configuration.Users.AutoSetupNewUsersWithVmUUID @@ -301,10 +286,10 @@ SELECT target_uuid, perm_level forget_cached_group_perms - return [repo_perm, vm_login_perm, *group_perms, self].compact + return [vm_login_perm, *group_perms, self].compact end - # delete user signatures, login, repo, and vm perms, and mark as inactive + # delete user signatures, login, and vm perms, and mark as inactive def unsetup if self.uuid == system_user_uuid raise "System root user cannot be deactivated" @@ -483,30 +468,13 @@ SELECT target_uuid, perm_level klass.where(column => uuid).update_all(column => new_user.uuid) end - # Need to update repository names to new username - if username - old_repo_name_re = /^#{Regexp.escape(username)}\// - Repository.where(:owner_uuid => uuid).each do |repo| - repo.owner_uuid = new_user.uuid - repo_name_sub = "#{new_user.username}/" - name = repo.name.sub(old_repo_name_re, repo_name_sub) - while (conflict = Repository.where(:name => name).first) != nil - repo_name_sub += "migrated" - name = repo.name.sub(old_repo_name_re, repo_name_sub) - end - repo.name = name - repo.save! - end - end - # References to the merged user's "home project" are updated to # point to new_owner_uuid. ActiveRecord::Base.descendants.reject(&:abstract_class?).each do |klass| next if [ApiClientAuthorization, AuthorizedKey, Link, - Log, - Repository].include?(klass) + Log].include?(klass) next if !klass.columns.collect(&:name).include?('owner_uuid') klass.where(owner_uuid: uuid).update_all(owner_uuid: new_owner_uuid) end @@ -889,24 +857,8 @@ SELECT target_uuid, perm_level merged end - def create_user_repo_link(repo_name) - # repo_name is optional - if not repo_name - logger.warn ("Repository name not given for #{self.uuid}.") - return - end - - repo = Repository.where(owner_uuid: uuid, name: repo_name).first_or_create! - logger.info { "repo uuid: " + repo[:uuid] } - repo_perm = Link.where(tail_uuid: uuid, head_uuid: repo.uuid, - link_class: "permission", - name: "can_manage").first_or_create! - logger.info { "repo permission: " + repo_perm[:uuid] } - return repo_perm - end - # create login permission for the given vm_uuid, if it does not already exist - def create_vm_login_permission_link(vm_uuid, repo_name) + def create_vm_login_permission_link(vm_uuid, username) # vm uuid is optional return if vm_uuid == "" @@ -924,11 +876,11 @@ SELECT target_uuid, perm_level login_perm = Link. where(login_attrs). - select { |link| link.properties["username"] == repo_name }. + select { |link| link.properties["username"] == username }. first login_perm ||= Link. - create(login_attrs.merge(properties: {"username" => repo_name})) + create(login_attrs.merge(properties: {"username" => username})) logger.info { "login permission: " + login_perm[:uuid] } login_perm @@ -1001,22 +953,6 @@ SELECT target_uuid, perm_level end end - def verify_repositories_empty - unless repositories.first.nil? - errors.add(:username, "can't be unset when the user owns repositories") - throw(:abort) - end - end - - def sync_repository_names - old_name_re = /^#{Regexp.escape(username_before_last_save)}\// - name_sub = "#{username}/" - repositories.find_each do |repo| - repo.name = repo.name.sub(old_name_re, name_sub) - repo.save! - end - end - def identity_url_nil_if_empty if identity_url == "" self.identity_url = nil diff --git a/services/api/config/arvados_config.rb b/services/api/config/arvados_config.rb index f8b9ff8ecd..c3a1bed482 100644 --- a/services/api/config/arvados_config.rb +++ b/services/api/config/arvados_config.rb @@ -84,7 +84,6 @@ arvcfg = ConfigLoader.new arvcfg.declare_config "ClusterID", NonemptyString, :uuid_prefix arvcfg.declare_config "ManagementToken", String, :ManagementToken arvcfg.declare_config "SystemRootToken", String -arvcfg.declare_config "Git.Repositories", String, :git_repositories_dir arvcfg.declare_config "API.DisabledAPIs", Hash, :disable_api_methods, ->(cfg, k, v) { arrayToHash cfg, "API.DisabledAPIs", v } arvcfg.declare_config "API.MaxRequestSize", Integer, :max_request_size arvcfg.declare_config "API.MaxIndexDatabaseRead", Integer, :max_index_database_read @@ -94,7 +93,6 @@ arvcfg.declare_config "API.RequestTimeout", ActiveSupport::Duration arvcfg.declare_config "API.AsyncPermissionsUpdateInterval", ActiveSupport::Duration, :async_permissions_update_interval arvcfg.declare_config "Users.AutoSetupNewUsers", Boolean, :auto_setup_new_users arvcfg.declare_config "Users.AutoSetupNewUsersWithVmUUID", String, :auto_setup_new_users_with_vm_uuid -arvcfg.declare_config "Users.AutoSetupNewUsersWithRepository", Boolean, :auto_setup_new_users_with_repository arvcfg.declare_config "Users.AutoSetupUsernameBlacklist", Hash, :auto_setup_name_blacklist, ->(cfg, k, v) { arrayToHash cfg, "Users.AutoSetupUsernameBlacklist", v } arvcfg.declare_config "Users.NewUsersAreActive", Boolean, :new_users_are_active arvcfg.declare_config "Users.AutoAdminUserWithEmail", String, :auto_admin_user @@ -132,33 +130,14 @@ arvcfg.declare_config "Containers.DefaultKeepCacheRAM", Integer, :container_defa arvcfg.declare_config "Containers.MaxDispatchAttempts", Integer, :max_container_dispatch_attempts arvcfg.declare_config "Containers.MaxRetryAttempts", Integer, :container_count_max arvcfg.declare_config "Containers.AlwaysUsePreemptibleInstances", Boolean, :preemptible_instances -arvcfg.declare_config "Containers.Logging.LogBytesPerEvent", Integer, :crunch_log_bytes_per_event -arvcfg.declare_config "Containers.Logging.LogSecondsBetweenEvents", ActiveSupport::Duration, :crunch_log_seconds_between_events -arvcfg.declare_config "Containers.Logging.LogThrottlePeriod", ActiveSupport::Duration, :crunch_log_throttle_period -arvcfg.declare_config "Containers.Logging.LogThrottleBytes", Integer, :crunch_log_throttle_bytes -arvcfg.declare_config "Containers.Logging.LogThrottleLines", Integer, :crunch_log_throttle_lines -arvcfg.declare_config "Containers.Logging.LimitLogBytesPerJob", Integer, :crunch_limit_log_bytes_per_job -arvcfg.declare_config "Containers.Logging.LogPartialLineThrottlePeriod", ActiveSupport::Duration, :crunch_log_partial_line_throttle_period arvcfg.declare_config "Containers.Logging.LogUpdatePeriod", ActiveSupport::Duration, :crunch_log_update_period arvcfg.declare_config "Containers.Logging.LogUpdateSize", Integer, :crunch_log_update_size -arvcfg.declare_config "Containers.Logging.MaxAge", ActiveSupport::Duration, :clean_container_log_rows_after -arvcfg.declare_config "Containers.SLURM.Managed.DNSServerConfDir", Pathname, :dns_server_conf_dir -arvcfg.declare_config "Containers.SLURM.Managed.DNSServerConfTemplate", Pathname, :dns_server_conf_template -arvcfg.declare_config "Containers.SLURM.Managed.DNSServerReloadCommand", String, :dns_server_reload_command -arvcfg.declare_config "Containers.SLURM.Managed.DNSServerUpdateCommand", String, :dns_server_update_command -arvcfg.declare_config "Containers.SLURM.Managed.ComputeNodeDomain", String, :compute_node_domain -arvcfg.declare_config "Containers.SLURM.Managed.ComputeNodeNameservers", Hash, :compute_node_nameservers, ->(cfg, k, v) { arrayToHash cfg, "Containers.SLURM.Managed.ComputeNodeNameservers", v } -arvcfg.declare_config "Containers.SLURM.Managed.AssignNodeHostname", String, :assign_node_hostname -arvcfg.declare_config "Containers.JobsAPI.Enable", String, :enable_legacy_jobs_api, ->(cfg, k, v) { ConfigLoader.set_cfg cfg, "Containers.JobsAPI.Enable", v.to_s } -arvcfg.declare_config "Containers.JobsAPI.GitInternalDir", String, :git_internal_dir arvcfg.declare_config "Mail.MailchimpAPIKey", String, :mailchimp_api_key arvcfg.declare_config "Mail.MailchimpListID", String, :mailchimp_list_id arvcfg.declare_config "Services.Controller.ExternalURL", URI arvcfg.declare_config "Services.Workbench1.ExternalURL", URI, :workbench_address arvcfg.declare_config "Services.Websocket.ExternalURL", URI, :websocket_address arvcfg.declare_config "Services.WebDAV.ExternalURL", URI, :keep_web_service_url -arvcfg.declare_config "Services.GitHTTP.ExternalURL", URI, :git_repo_https_base -arvcfg.declare_config "Services.GitSSH.ExternalURL", URI, :git_repo_ssh_base, ->(cfg, k, v) { ConfigLoader.set_cfg cfg, "Services.GitSSH.ExternalURL", "ssh://#{v}" } arvcfg.declare_config "RemoteClusters", Hash, :remote_hosts, ->(cfg, k, v) { h = if cfg["RemoteClusters"] then cfg["RemoteClusters"].deep_dup diff --git a/services/api/config/routes.rb b/services/api/config/routes.rb index b87e86f664..df3c057b57 100644 --- a/services/api/config/routes.rb +++ b/services/api/config/routes.rb @@ -34,8 +34,6 @@ Rails.application.routes.draw do post 'trash', on: :member post 'untrash', on: :member end - resources :humans - resources :job_tasks resources :containers do get 'auth', on: :member post 'lock', on: :member @@ -47,33 +45,12 @@ Rails.application.routes.draw do resources :container_requests do get 'container_status', on: :member end - resources :jobs do - get 'queue', on: :collection - get 'queue_size', on: :collection - post 'cancel', on: :member - post 'lock', on: :member - end - resources :keep_disks do - post 'ping', on: :collection - end resources :keep_services do get 'accessible', on: :collection end resources :links resources :logs - resources :nodes do - post 'ping', on: :member - end - resources :pipeline_instances do - post 'cancel', on: :member - end - resources :pipeline_templates resources :workflows - resources :repositories do - get 'get_all_permissions', on: :collection - end - resources :specimens - resources :traits resources :user_agreements do get 'signatures', on: :collection post 'sign', on: :collection diff --git a/services/api/db/migrate/20240329173437_add_output_glob_to_containers.rb b/services/api/db/migrate/20240329173437_add_output_glob_to_containers.rb new file mode 100644 index 0000000000..481cad123f --- /dev/null +++ b/services/api/db/migrate/20240329173437_add_output_glob_to_containers.rb @@ -0,0 +1,10 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +class AddOutputGlobToContainers < ActiveRecord::Migration[7.0] + def change + add_column :containers, :output_glob, :text, default: '[]' + add_column :container_requests, :output_glob, :text, default: '[]' + end +end diff --git a/services/api/db/migrate/20240402162733_add_output_glob_index_to_containers.rb b/services/api/db/migrate/20240402162733_add_output_glob_index_to_containers.rb new file mode 100644 index 0000000000..00050f8a78 --- /dev/null +++ b/services/api/db/migrate/20240402162733_add_output_glob_index_to_containers.rb @@ -0,0 +1,17 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +require './db/migrate/20161213172944_full_text_search_indexes' + +class AddOutputGlobIndexToContainers < ActiveRecord::Migration[4.2] + def up + ActiveRecord::Base.connection.execute 'DROP INDEX index_containers_on_reuse_columns' + ActiveRecord::Base.connection.execute 'CREATE INDEX index_containers_on_reuse_columns on containers (md5(command), cwd, md5(environment), output_path, md5(output_glob), container_image, md5(mounts), secret_mounts_md5, md5(runtime_constraints))' + FullTextSearchIndexes.new.replace_index('container_requests') + end + def down + ActiveRecord::Base.connection.execute 'DROP INDEX index_containers_on_reuse_columns' + ActiveRecord::Base.connection.execute 'CREATE INDEX index_containers_on_reuse_columns on containers (md5(command), cwd, md5(environment), output_path, container_image, md5(mounts), secret_mounts_md5, md5(runtime_constraints))' + end +end diff --git a/services/api/db/structure.sql b/services/api/db/structure.sql index c0d4263d97..08862c60c2 100644 --- a/services/api/db/structure.sql +++ b/services/api/db/structure.sql @@ -568,7 +568,8 @@ CREATE TABLE public.container_requests ( runtime_token text, output_storage_classes jsonb DEFAULT '["default"]'::jsonb, output_properties jsonb DEFAULT '{}'::jsonb, - cumulative_cost double precision DEFAULT 0.0 NOT NULL + cumulative_cost double precision DEFAULT 0.0 NOT NULL, + output_glob text DEFAULT '[]'::text ); @@ -634,7 +635,8 @@ CREATE TABLE public.containers ( output_storage_classes jsonb DEFAULT '["default"]'::jsonb, output_properties jsonb DEFAULT '{}'::jsonb, cost double precision DEFAULT 0.0 NOT NULL, - subrequests_cost double precision DEFAULT 0.0 NOT NULL + subrequests_cost double precision DEFAULT 0.0 NOT NULL, + output_glob text DEFAULT '[]'::text ); @@ -1855,6 +1857,13 @@ CREATE INDEX collections_search_index ON public.collections USING btree (owner_u CREATE INDEX collections_trgm_text_search_idx ON public.collections USING gin (((((((((((((((((((COALESCE(owner_uuid, ''::character varying))::text || ' '::text) || (COALESCE(modified_by_client_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(modified_by_user_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(portable_data_hash, ''::character varying))::text) || ' '::text) || (COALESCE(uuid, ''::character varying))::text) || ' '::text) || (COALESCE(name, ''::character varying))::text) || ' '::text) || (COALESCE(description, ''::character varying))::text) || ' '::text) || COALESCE((properties)::text, ''::text)) || ' '::text) || COALESCE(file_names, ''::text))) public.gin_trgm_ops); +-- +-- Name: container_requests_full_text_search_idx; Type: INDEX; Schema: public; Owner: - +-- + +CREATE INDEX container_requests_full_text_search_idx ON public.container_requests USING gin (to_tsvector('english'::regconfig, substr((((((((((((((((((((((((((((((((((((((((((((((COALESCE(uuid, ''::character varying))::text || ' '::text) || (COALESCE(owner_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(modified_by_client_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(modified_by_user_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(name, ''::character varying))::text) || ' '::text) || COALESCE(description, ''::text)) || ' '::text) || COALESCE((properties)::text, ''::text)) || ' '::text) || (COALESCE(state, ''::character varying))::text) || ' '::text) || (COALESCE(requesting_container_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(container_uuid, ''::character varying))::text) || ' '::text) || COALESCE(runtime_constraints, ''::text)) || ' '::text) || (COALESCE(container_image, ''::character varying))::text) || ' '::text) || COALESCE(environment, ''::text)) || ' '::text) || (COALESCE(cwd, ''::character varying))::text) || ' '::text) || COALESCE(command, ''::text)) || ' '::text) || (COALESCE(output_path, ''::character varying))::text) || ' '::text) || COALESCE(filters, ''::text)) || ' '::text) || COALESCE(scheduling_parameters, ''::text)) || ' '::text) || (COALESCE(output_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(log_uuid, ''::character varying))::text) || ' '::text) || (COALESCE(output_name, ''::character varying))::text) || ' '::text) || COALESCE((output_properties)::text, ''::text)) || ' '::text) || COALESCE(output_glob, ''::text)), 0, 8000))); + + -- -- Name: container_requests_index_on_properties; Type: INDEX; Schema: public; Owner: - -- @@ -2167,7 +2176,7 @@ CREATE INDEX index_containers_on_queued_state ON public.containers USING btree ( -- Name: index_containers_on_reuse_columns; Type: INDEX; Schema: public; Owner: - -- -CREATE INDEX index_containers_on_reuse_columns ON public.containers USING btree (md5(command), cwd, md5(environment), output_path, container_image, md5(mounts), secret_mounts_md5, md5(runtime_constraints)); +CREATE INDEX index_containers_on_reuse_columns ON public.containers USING btree (md5(command), cwd, md5(environment), output_path, md5(output_glob), container_image, md5(mounts), secret_mounts_md5, md5(runtime_constraints)); -- @@ -3316,4 +3325,6 @@ INSERT INTO "schema_migrations" (version) VALUES ('20230815160000'), ('20230821000000'), ('20230922000000'), -('20231013000000'); +('20231013000000'), +('20240329173437'), +('20240402162733'); diff --git a/services/api/lib/can_be_an_owner.rb b/services/api/lib/can_be_an_owner.rb index e09037819c..995f6f334c 100644 --- a/services/api/lib/can_be_an_owner.rb +++ b/services/api/lib/can_be_an_owner.rb @@ -14,11 +14,23 @@ module CanBeAnOwner # record when other objects refer to it. ActiveRecord::Base.connection.tables.each do |t| next if t == base.table_name - next if t == 'schema_migrations' - next if t == 'permission_refresh_lock' - next if t == 'ar_internal_metadata' - next if t == 'commit_ancestors' - next if t == 'commits' + next if t.in?([ + 'schema_migrations', + 'permission_refresh_lock', + 'ar_internal_metadata', + 'commit_ancestors', + 'commits', + 'humans', + 'jobs', + 'job_tasks', + 'keep_disks', + 'nodes', + 'pipeline_instances', + 'pipeline_templates', + 'repositories', + 'specimens', + 'traits', + ]) klass = t.classify.constantize next unless klass and 'owner_uuid'.in?(klass.columns.collect(&:name)) base.has_many(t.to_sym, diff --git a/services/api/script/arvados-git-sync.rb b/services/api/script/arvados-git-sync.rb deleted file mode 100755 index 9f8f050c10..0000000000 --- a/services/api/script/arvados-git-sync.rb +++ /dev/null @@ -1,271 +0,0 @@ -#!/usr/bin/env ruby -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'rubygems' -require 'pp' -require 'arvados' -require 'tempfile' -require 'yaml' -require 'fileutils' - -# This script does the actual gitolite config management on disk. -# -# Ward Vandewege - -# Default is development -production = ARGV[0] == "production" - -ENV["RAILS_ENV"] = "development" -ENV["RAILS_ENV"] = "production" if production - -DEBUG = 1 - -# load and merge in the environment-specific application config info -# if present, overriding base config parameters as specified -path = File.absolute_path('../../config/arvados-clients.yml', __FILE__) -if File.exist?(path) then - cp_config = File.open(path) do |f| - YAML.safe_load(f, filename: path)[ENV['RAILS_ENV']] - end -else - puts "Please create a\n #{path}\n file" - exit 1 -end - -gitolite_url = cp_config['gitolite_url'] -gitolite_arvados_git_user_key = cp_config['gitolite_arvados_git_user_key'] - -gitolite_tmpdir = cp_config['gitolite_tmp'] -gitolite_admin = File.join(gitolite_tmpdir, 'gitolite-admin') -gitolite_admin_keydir = File.join(gitolite_admin, 'keydir') -gitolite_keydir = File.join(gitolite_admin, 'keydir', 'arvados') - -ENV['ARVADOS_API_HOST'] = cp_config['arvados_api_host'] -ENV['ARVADOS_API_TOKEN'] = cp_config['arvados_api_token'] -if cp_config['arvados_api_host_insecure'] - ENV['ARVADOS_API_HOST_INSECURE'] = 'true' -else - ENV.delete('ARVADOS_API_HOST_INSECURE') -end - -def ensure_directory(path, mode) - begin - Dir.mkdir(path, mode) - rescue Errno::EEXIST - end -end - -def replace_file(path, contents) - unlink_now = true - dirname, basename = File.split(path) - FileUtils.mkpath(dirname) - new_file = Tempfile.new([basename, ".tmp"], dirname) - begin - new_file.write(contents) - new_file.flush - File.rename(new_file, path) - unlink_now = false - ensure - new_file.close(unlink_now) - end -end - -def file_has_contents?(path, contents) - begin - IO.read(path) == contents - rescue Errno::ENOENT - false - end -end - -module TrackCommitState - module ClassMethods - # Note that all classes that include TrackCommitState will have - # @@need_commit = true if any of them set it. Since this flag reports - # a boolean state of the underlying git repository, that's OK in the - # current implementation. - @@need_commit = false - - def changed? - @@need_commit - end - - def ensure_in_git(path, contents) - unless file_has_contents?(path, contents) - replace_file(path, contents) - system("git", "add", path) - @@need_commit = true - end - end - end - - def ensure_in_git(path, contents) - self.class.ensure_in_git(path, contents) - end - - def self.included(base) - base.extend(ClassMethods) - end -end - -class UserSSHKeys - include TrackCommitState - - def initialize(user_keys_map, key_dir) - @user_keys_map = user_keys_map - @key_dir = key_dir - @installed = {} - end - - def install(filename, pubkey) - unless pubkey.nil? - key_path = File.join(@key_dir, filename) - ensure_in_git(key_path, pubkey) - end - @installed[filename] = true - end - - def ensure_keys_for_user(user_uuid) - return unless key_list = @user_keys_map.delete(user_uuid) - key_list.map { |k| k[:public_key] }.compact.each_with_index do |pubkey, ii| - # Handle putty-style ssh public keys - pubkey.sub!(/^(Comment: "r[^\n]*\n)(.*)$/m,'ssh-rsa \2 \1') - pubkey.sub!(/^(Comment: "d[^\n]*\n)(.*)$/m,'ssh-dss \2 \1') - pubkey.gsub!(/\n/,'') - pubkey.strip! - install("#{user_uuid}@#{ii}.pub", pubkey) - end - end - - def installed?(filename) - @installed[filename] - end -end - -class Repository - include TrackCommitState - - @@aliases = {} - - def initialize(arv_repo, user_keys) - @arv_repo = arv_repo - @user_keys = user_keys - end - - def self.ensure_system_config(conf_root) - ensure_in_git(File.join(conf_root, "conf", "gitolite.conf"), - %Q{include "auto/*.conf"\ninclude "admin/*.conf"\n}) - ensure_in_git(File.join(conf_root, "arvadosaliases.pl"), alias_config) - - conf_path = File.join(conf_root, "conf", "admin", "arvados.conf") - conf_file = %Q{ -@arvados_git_user = arvados_git_user - -repo gitolite-admin - RW = @arvados_git_user - -} - ensure_directory(File.dirname(conf_path), 0755) - ensure_in_git(conf_path, conf_file) - end - - def ensure_config(conf_root) - if name and (File.exist?(auto_conf_path(conf_root, name))) - # This gitolite installation knows the repository by name, rather than - # UUID. Leave it configured that way until a separate migration is run. - basename = name - else - basename = uuid - @@aliases[name] = uuid unless name.nil? - end - conf_file = "\nrepo #{basename}\n" - @arv_repo[:user_permissions].sort.each do |user_uuid, perm| - conf_file += "\t#{perm[:gitolite_permissions]}\t= #{user_uuid}\n" - @user_keys.ensure_keys_for_user(user_uuid) - end - ensure_in_git(auto_conf_path(conf_root, basename), conf_file) - end - - private - - def auto_conf_path(conf_root, basename) - File.join(conf_root, "conf", "auto", "#{basename}.conf") - end - - def uuid - @arv_repo[:uuid] - end - - def name - if @arv_repo[:name].nil? - nil - else - @clean_name ||= - @arv_repo[:name].sub(/^[^A-Za-z]+/, "").gsub(/[^\w\.\/]/, "") - end - end - - def self.alias_config - conf_s = "{\n" - @@aliases.sort.each do |(repo_name, repo_uuid)| - conf_s += "\t'#{repo_name}' \t=> '#{repo_uuid}',\n" - end - conf_s += "};\n" - conf_s - end -end - -begin - # Get our local gitolite-admin repo up to snuff - if not File.exist?(gitolite_admin) then - ensure_directory(gitolite_tmpdir, 0700) - Dir.chdir(gitolite_tmpdir) - `git clone #{gitolite_url}` - Dir.chdir(gitolite_admin) - else - Dir.chdir(gitolite_admin) - `git pull` - end - - arv = Arvados.new - permissions = arv.repository.get_all_permissions - - ensure_directory(gitolite_keydir, 0700) - admin_user_ssh_keys = UserSSHKeys.new(permissions[:user_keys], gitolite_admin_keydir) - # Make sure the arvados_git_user key is installed; put it in gitolite_admin_keydir - # because that is where gitolite will try to put it if we do not. - admin_user_ssh_keys.install('arvados_git_user.pub', gitolite_arvados_git_user_key) - - user_ssh_keys = UserSSHKeys.new(permissions[:user_keys], gitolite_keydir) - permissions[:repositories].each do |repo_record| - repo = Repository.new(repo_record, user_ssh_keys) - repo.ensure_config(gitolite_admin) - end - Repository.ensure_system_config(gitolite_admin) - - # Clean up public key files that should not be present - Dir.chdir(gitolite_keydir) - stale_keys = Dir.glob('*.pub').reject do |key_file| - user_ssh_keys.installed?(key_file) - end - if stale_keys.any? - stale_keys.each { |key_file| puts "Extra file #{key_file}" } - system("git", "rm", "--quiet", *stale_keys) - end - - if UserSSHKeys.changed? or Repository.changed? or stale_keys.any? - message = "#{Time.now().to_s}: update from API" - Dir.chdir(gitolite_admin) - `git add --all` - `git commit -m '#{message}'` - `git push` - end - -rescue => bang - puts "Error: " + bang.to_s - puts bang.backtrace.join("\n") - exit 1 -end - diff --git a/services/api/script/migrate-gitolite-to-uuid-storage.rb b/services/api/script/migrate-gitolite-to-uuid-storage.rb deleted file mode 100755 index 98f25ca537..0000000000 --- a/services/api/script/migrate-gitolite-to-uuid-storage.rb +++ /dev/null @@ -1,226 +0,0 @@ -#!/usr/bin/env ruby -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -# -# Prior to April 2015, Arvados Gitolite integration stored repositories by -# name. To improve user repository management, we switched to storing -# repositories by UUID, and aliasing them to names. This makes it easy to -# have rich name hierarchies, and allow users to rename repositories. -# -# This script will migrate a name-based Gitolite configuration to a UUID-based -# one. To use it: -# -# 1. Change the value of REPOS_DIR below, if needed. -# 2. Install this script in the same directory as `update-gitolite.rb`. -# 3. Ensure that no *other* users can access Gitolite: edit gitolite's -# authorized_keys file so it only contains the arvados_git_user key, -# and disable the update-gitolite cron job. -# 4. Run this script: `ruby migrate-gitolite-to-uuid-storage.rb production`. -# 5. Undo step 3. - -require 'rubygems' -require 'pp' -require 'arvados' -require 'tempfile' -require 'yaml' - -REPOS_DIR = "/var/lib/gitolite/repositories" - -# Default is development -production = ARGV[0] == "production" - -ENV["RAILS_ENV"] = "development" -ENV["RAILS_ENV"] = "production" if production - -DEBUG = 1 - -# load and merge in the environment-specific application config info -# if present, overriding base config parameters as specified -path = File.dirname(__FILE__) + '/config/arvados-clients.yml' -if File.exist?(path) then - cp_config = File.open(path) do |f| - YAML.safe_load(f, filename: path)[ENV['RAILS_ENV']] - end -else - puts "Please create a\n " + File.dirname(__FILE__) + "/config/arvados-clients.yml\n file" - exit 1 -end - -gitolite_url = cp_config['gitolite_url'] -gitolite_arvados_git_user_key = cp_config['gitolite_arvados_git_user_key'] - -gitolite_tmpdir = File.join(File.absolute_path(File.dirname(__FILE__)), - cp_config['gitolite_tmp']) -gitolite_admin = File.join(gitolite_tmpdir, 'gitolite-admin') -gitolite_keydir = File.join(gitolite_admin, 'keydir', 'arvados') - -ENV['ARVADOS_API_HOST'] = cp_config['arvados_api_host'] -ENV['ARVADOS_API_TOKEN'] = cp_config['arvados_api_token'] -if cp_config['arvados_api_host_insecure'] - ENV['ARVADOS_API_HOST_INSECURE'] = 'true' -else - ENV.delete('ARVADOS_API_HOST_INSECURE') -end - -def ensure_directory(path, mode) - begin - Dir.mkdir(path, mode) - rescue Errno::EEXIST - end -end - -def replace_file(path, contents) - unlink_now = true - dirname, basename = File.split(path) - new_file = Tempfile.new([basename, ".tmp"], dirname) - begin - new_file.write(contents) - new_file.flush - File.rename(new_file, path) - unlink_now = false - ensure - new_file.close(unlink_now) - end -end - -def file_has_contents?(path, contents) - begin - IO.read(path) == contents - rescue Errno::ENOENT - false - end -end - -module TrackCommitState - module ClassMethods - # Note that all classes that include TrackCommitState will have - # @@need_commit = true if any of them set it. Since this flag reports - # a boolean state of the underlying git repository, that's OK in the - # current implementation. - @@need_commit = false - - def changed? - @@need_commit - end - - def ensure_in_git(path, contents) - unless file_has_contents?(path, contents) - replace_file(path, contents) - system("git", "add", path) - @@need_commit = true - end - end - end - - def ensure_in_git(path, contents) - self.class.ensure_in_git(path, contents) - end - - def self.included(base) - base.extend(ClassMethods) - end -end - -class Repository - include TrackCommitState - - @@aliases = {} - - def initialize(arv_repo) - @arv_repo = arv_repo - end - - def self.ensure_system_config(conf_root) - ensure_in_git(File.join(conf_root, "arvadosaliases.pl"), alias_config) - end - - def self.rename_repos(repos_root) - @@aliases.each_pair do |uuid, name| - begin - File.rename(File.join(repos_root, "#{name}.git/"), - File.join(repos_root, "#{uuid}.git")) - rescue Errno::ENOENT - end - if name == "arvados" - Dir.chdir(repos_root) { File.symlink("#{uuid}.git/", "arvados.git") } - end - end - end - - def ensure_config(conf_root) - return if name.nil? - @@aliases[uuid] = name - name_conf_path = auto_conf_path(conf_root, name) - return unless File.exist?(name_conf_path) - conf_file = IO.read(name_conf_path) - conf_file.gsub!(/^repo #{Regexp.escape(name)}$/m, "repo #{uuid}") - ensure_in_git(auto_conf_path(conf_root, uuid), conf_file) - File.unlink(name_conf_path) - system("git", "rm", "--quiet", name_conf_path) - end - - private - - def auto_conf_path(conf_root, basename) - File.join(conf_root, "conf", "auto", "#{basename}.conf") - end - - def uuid - @arv_repo[:uuid] - end - - def name - if @arv_repo[:name].nil? - nil - else - @clean_name ||= - @arv_repo[:name].sub(/^[^A-Za-z]+/, "").gsub(/[^\w\.\/]/, "") - end - end - - def self.alias_config - conf_s = "{\n" - @@aliases.sort.each do |(repo_name, repo_uuid)| - conf_s += "\t'#{repo_name}' \t=> '#{repo_uuid}',\n" - end - conf_s += "};\n" - conf_s - end -end - -begin - # Get our local gitolite-admin repo up to snuff - if not File.exist?(gitolite_admin) then - ensure_directory(gitolite_tmpdir, 0700) - Dir.chdir(gitolite_tmpdir) - `git clone #{gitolite_url}` - Dir.chdir(gitolite_admin) - else - Dir.chdir(gitolite_admin) - `git pull` - end - - arv = Arvados.new - permissions = arv.repository.get_all_permissions - - permissions[:repositories].each do |repo_record| - repo = Repository.new(repo_record) - repo.ensure_config(gitolite_admin) - end - Repository.ensure_system_config(gitolite_admin) - - message = "#{Time.now().to_s}: migrate to storing repositories by UUID" - Dir.chdir(gitolite_admin) - `git add --all` - `git commit -m '#{message}'` - Repository.rename_repos(REPOS_DIR) - `git push` - -rescue => bang - puts "Error: " + bang.to_s - puts bang.backtrace.join("\n") - exit 1 -end - diff --git a/services/api/test/fixtures/api_client_authorizations.yml b/services/api/test/fixtures/api_client_authorizations.yml index c6ade21f8b..882937034b 100644 --- a/services/api/test/fixtures/api_client_authorizations.yml +++ b/services/api/test/fixtures/api_client_authorizations.yml @@ -128,14 +128,6 @@ active_userlist: expires_at: 2038-01-01 00:00:00 scopes: ["GET /arvados/v1/users"] -active_specimens: - uuid: zzzzz-gj3su-177z32aux8dg2s1 - api_client: untrusted - user: active - api_token: activespecimensabcdefghijklmnopqrstuvwxyz123456890 - expires_at: 2038-01-01 00:00:00 - scopes: ["GET /arvados/v1/specimens/"] - active_apitokens: uuid: zzzzz-gj3su-187z32aux8dg2s1 api_client: trusted_workbench @@ -160,14 +152,21 @@ spectator: api_token: zw2f4gwx8hw8cjre7yp6v1zylhrhn3m5gvjq73rtpwhmknrybu expires_at: 2038-01-01 00:00:00 -spectator_specimens: +foo: + uuid: zzzzz-gj3su-fohzae5ib1aseiv + api_client: untrusted + user: user_foo_in_sharing_group + api_token: lokah4xip8ahgee8oof5zitah3ohdai6je9cu1uogh4bai3ohw + expires_at: 2038-01-01 00:00:00 + +foo_collections: uuid: zzzzz-gj3su-217z32aux8dg2s1 api_client: untrusted - user: spectator - api_token: spectatorspecimensabcdefghijklmnopqrstuvwxyz123245 + user: user_foo_in_sharing_group + api_token: spectatorcollectionscdefghijklmnopqrstuvwxyz123245 expires_at: 2038-01-01 00:00:00 - scopes: ["GET /arvados/v1/specimens", "GET /arvados/v1/specimens/", - "POST /arvados/v1/specimens"] + scopes: ["GET /arvados/v1/collections", "GET /arvados/v1/collections/", + "POST /arvados/v1/collections"] inactive: uuid: zzzzz-gj3su-227z32aux8dg2s1 diff --git a/services/api/test/fixtures/collections.yml b/services/api/test/fixtures/collections.yml index 72aad1d68e..a193150e29 100644 --- a/services/api/test/fixtures/collections.yml +++ b/services/api/test/fixtures/collections.yml @@ -451,22 +451,6 @@ unique_expired_collection2: manifest_text: ". 29d7797f1888013986899bc9083783fa+3 0:3:expired2\n" name: unique_expired_collection2 -# a collection with a log file that can be parsed by the log viewer -# This collection hash matches the following log text: -# 2014-01-01_12:00:01 zzzzz-8i9sb-abcdefghijklmno 0 log message 1 -# 2014-01-01_12:00:02 zzzzz-8i9sb-abcdefghijklmno 0 log message 2 -# 2014-01-01_12:00:03 zzzzz-8i9sb-abcdefghijklmno 0 log message 3 -# -real_log_collection: - uuid: zzzzz-4zz18-op4e2lbej01tcvu - current_version_uuid: zzzzz-4zz18-op4e2lbej01tcvu - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-09-01 12:00:00 - modified_at: 2014-09-01 12:00:00 - portable_data_hash: 0b9a7787660e1fce4a93f33e01376ba6+81 - manifest_text: ". cdd549ae79fe6640fa3d5c6261d8303c+195 0:195:zzzzz-8i9sb-0vsrcqi7whchuil.log.txt\n" - name: real_log_collection - collection_in_home_project_with_same_name_as_in_aproject: uuid: zzzzz-4zz18-12342x4u7ftabcd current_version_uuid: zzzzz-4zz18-12342x4u7ftabcd @@ -1076,6 +1060,18 @@ collection_with_uri_prop: properties: "http://schema.org/example": "value1" +container_log_collection: + uuid: zzzzz-4zz18-logcollection00 + current_version_uuid: zzzzz-4zz18-logcollection00 + portable_data_hash: b1e66f713c04d28ddbaced89096f4838+210 + owner_uuid: zzzzz-tpzed-000000000000000 + created_at: 2020-10-29T00:51:44.075594000Z + modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr + modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f + modified_at: 2020-10-29T00:51:44.072109000Z + manifest_text: ". 8c12f5f5297b7337598170c6f531fcee+7882 0:0:arv-mount.txt 0:1910:container.json 1910:1264:crunch-run.txt 3174:1005:crunchstat.txt 4179:659:hoststat.txt 4838:2811:node-info.txt 7649:233:node.json 0:0:stderr.txt\n" + name: a real log collection for a completed container + log_collection: uuid: zzzzz-4zz18-logcollection01 current_version_uuid: zzzzz-4zz18-logcollection01 @@ -1086,7 +1082,7 @@ log_collection: modified_by_user_uuid: zzzzz-tpzed-d9tiejq69daie8f modified_at: 2020-10-29T00:51:44.072109000Z manifest_text: ". 8c12f5f5297b7337598170c6f531fcee+7882 0:0:arv-mount.txt 0:1910:container.json 1910:1264:crunch-run.txt 3174:1005:crunchstat.txt 4179:659:hoststat.txt 4838:2811:node-info.txt 7649:233:node.json 0:0:stderr.txt\n./log\\040for\\040container\\040ce8i5-dz642-h4kd64itncdcz8l 8c12f5f5297b7337598170c6f531fcee+7882 0:0:arv-mount.txt 0:1910:container.json 1910:1264:crunch-run.txt 3174:1005:crunchstat.txt 4179:659:hoststat.txt 4838:2811:node-info.txt 7649:233:node.json 0:0:stderr.txt\n" - name: a real log collection for a completed container + name: a real log collection for a completed container request log_collection2: uuid: zzzzz-4zz18-logcollection02 diff --git a/services/api/test/fixtures/container_requests.yml b/services/api/test/fixtures/container_requests.yml index 71c7a54df3..3b035416cb 100644 --- a/services/api/test/fixtures/container_requests.yml +++ b/services/api/test/fixtures/container_requests.yml @@ -1056,6 +1056,36 @@ runtime_token: ram: 123 mounts: {} +read_foo_write_bar: + uuid: zzzzz-xvdhp-readfoowritebar + owner_uuid: zzzzz-tpzed-000000000000000 + state: Final + created_at: 2024-01-11 11:11:11.111111111 Z + updated_at: 2024-01-11 11:11:11.111111111 Z + modified_at: 2024-01-11 11:11:11.111111111 Z + modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz + container_image: test + cwd: / + mounts: + stdin: + kind: collection + portable_data_hash: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45 + path: /foo + stdout: + kind: file + path: /mnt/out/bar + /mnt/out: + kind: tmp + capacity: 1000 + container_uuid: zzzzz-dz642-readfoowritebar + log_uuid: zzzzz-4zz18-logcollection01 + output_uuid: zzzzz-4zz18-ehbhgtheo8909or + output_path: test + command: ["echo", "-n", "bar"] + runtime_constraints: + ram: 10000000 + vcpus: 1 + # Test Helper trims the rest of the file diff --git a/services/api/test/fixtures/containers.yml b/services/api/test/fixtures/containers.yml index 46bc1e50f9..8e40554a9b 100644 --- a/services/api/test/fixtures/containers.yml +++ b/services/api/test/fixtures/containers.yml @@ -485,3 +485,36 @@ cuda_container: device_count: 1 secret_mounts: {} secret_mounts_md5: 99914b932bd37a50b983c5e7c90ae93b + +read_foo_write_bar: + uuid: zzzzz-dz642-readfoowritebar + owner_uuid: zzzzz-tpzed-000000000000000 + state: Complete + exit_code: 0 + priority: 1 + created_at: 2024-01-11 11:11:11.111111111 Z + updated_at: 2024-01-11 11:11:11.111111111 Z + started_at: 2024-01-11 11:11:11.111111111 Z + finished_at: 2024-01-12 11:12:13.111111111 Z + container_image: test + cwd: / + mounts: + stdin: + kind: collection + portable_data_hash: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45 + path: /foo + stdout: + kind: file + path: /mnt/out/bar + /mnt/out: + kind: tmp + capacity: 1000 + log: ea10d51bcf88862dbcc36eb292017dfd+45 + output: fa7aeb5140e2848d39b416daeef4ffc5+45 + output_path: test + command: ["echo", "-n", "bar"] + runtime_constraints: + ram: 10000000 + vcpus: 1 + secret_mounts: {} + secret_mounts_md5: 99914b932bd37a50b983c5e7c90ae93b diff --git a/services/api/test/fixtures/humans.yml b/services/api/test/fixtures/humans.yml deleted file mode 100644 index eee61efefe..0000000000 --- a/services/api/test/fixtures/humans.yml +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -# File exists to ensure the table gets cleared during DatabaseController#reset diff --git a/services/api/test/fixtures/job_tasks.yml b/services/api/test/fixtures/job_tasks.yml deleted file mode 100644 index 6a857a02f2..0000000000 --- a/services/api/test/fixtures/job_tasks.yml +++ /dev/null @@ -1,15 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -running_job_task_1: - uuid: zzzzz-ot0gb-runningjobtask1 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: <%= 3.minute.ago.to_fs(:db) %> - job_uuid: zzzzz-8i9sb-with2components - -running_job_task_2: - uuid: zzzzz-ot0gb-runningjobtask2 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: <%= 3.minute.ago.to_fs(:db) %> - job_uuid: zzzzz-8i9sb-with2components diff --git a/services/api/test/fixtures/jobs.yml b/services/api/test/fixtures/jobs.yml deleted file mode 100644 index 54b38259ba..0000000000 --- a/services/api/test/fixtures/jobs.yml +++ /dev/null @@ -1,768 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -running: - uuid: zzzzz-8i9sb-pshmckwoma9plh7 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 2.7.minute.ago.to_fs(:db) %> - started_at: <%= 2.7.minute.ago.to_fs(:db) %> - finished_at: ~ - script: hash - repository: active/foo - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -running_cancelled: - uuid: zzzzz-8i9sb-4cf0nhn6xte809j - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: <%= 1.minute.ago.to_fs(:db) %> - cancelled_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - created_at: <%= 4.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: ~ - script: hash - repository: active/foo - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Cancelled - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -uses_nonexistent_script_version: - uuid: zzzzz-8i9sb-7m339pu0x9mla88 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - created_at: <%= 5.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: <%= 2.minute.ago.to_fs(:db) %> - script: hash - repository: active/foo - running: false - success: true - output: d41d8cd98f00b204e9800998ecf8427e+0 - priority: 0 - log: d41d8cd98f00b204e9800998ecf8427e+0 - is_locked_by_uuid: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 0 - done: 1 - runtime_constraints: {} - state: Complete - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -foobar: - uuid: zzzzz-8i9sb-aceg2bnq7jt7kon - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - script: hash - repository: active/foo - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - script_parameters: - input: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45 - created_at: <%= 4.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: <%= 2.minute.ago.to_fs(:db) %> - running: false - success: true - output: fa7aeb5140e2848d39b416daeef4ffc5+45 - priority: 0 - log: ea10d51bcf88862dbcc36eb292017dfd+45 - is_locked_by_uuid: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 0 - done: 1 - runtime_constraints: {} - state: Complete - script_parameters_digest: 03a43a7d84f7fb022467b876c2950acd - -barbaz: - uuid: zzzzz-8i9sb-cjs4pklxxjykyuq - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: 1 - created_at: <%= 4.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: <%= 2.minute.ago.to_fs(:db) %> - running: false - success: true - repository: active/foo - output: ea10d51bcf88862dbcc36eb292017dfd+45 - priority: 0 - log: d41d8cd98f00b204e9800998ecf8427e+0 - is_locked_by_uuid: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 0 - done: 1 - runtime_constraints: {} - state: Complete - script_parameters_digest: c3d19d3ec50ac0914baa56b149640f73 - -runningbarbaz: - uuid: zzzzz-8i9sb-cjs4pklxxjykyuj - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: 1 - created_at: <%= 4.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: <%= 2.minute.ago.to_fs(:db) %> - running: true - success: ~ - repository: active/foo - output: ea10d51bcf88862dbcc36eb292017dfd+45 - priority: 0 - log: d41d8cd98f00b204e9800998ecf8427e+0 - is_locked_by_uuid: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 1 - done: 0 - runtime_constraints: {} - state: Running - script_parameters_digest: c3d19d3ec50ac0914baa56b149640f73 - -previous_job_run: - uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - created_at: <%= 14.minute.ago.to_fs(:db) %> - finished_at: <%= 13.minutes.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "1" - success: true - log: d41d8cd98f00b204e9800998ecf8427e+0 - output: ea10d51bcf88862dbcc36eb292017dfd+45 - state: Complete - script_parameters_digest: a5f03bbfb8ba88a2efe4a7852671605b - -previous_job_run_nil_log: - uuid: zzzzz-8i9sb-cjs4pklxxjykqq3 - created_at: <%= 14.minute.ago.to_fs(:db) %> - finished_at: <%= 13.minutes.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "3" - success: true - log: ~ - output: ea10d51bcf88862dbcc36eb292017dfd+45 - state: Complete - script_parameters_digest: 445702df4029b8a6e7075b451ff1256a - -previous_ancient_job_run: - uuid: zzzzz-8i9sb-ahd7cie8jah9qui - created_at: <%= 366.days.ago.to_fs(:db) %> - finished_at: <%= 365.days.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "2" - success: true - log: d41d8cd98f00b204e9800998ecf8427e+0 - output: ea10d51bcf88862dbcc36eb292017dfd+45 - state: Complete - script_parameters_digest: 174dd339d44f2b259fadbab7ebdb8df9 - -previous_docker_job_run: - uuid: zzzzz-8i9sb-k6emstgk4kw4yhi - created_at: <%= 14.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "1" - runtime_constraints: - docker_image: arvados/apitestfixture - success: true - output: ea10d51bcf88862dbcc36eb292017dfd+45 - docker_image_locator: fa3c1a9cb6783f85f2ecda037e07b8c3+167 - state: Complete - script_parameters_digest: a5f03bbfb8ba88a2efe4a7852671605b - log: ea10d51bcf88862dbcc36eb292017dfd+45 - -previous_ancient_docker_image_job_run: - uuid: zzzzz-8i9sb-t3b460aolxxuldl - created_at: <%= 144.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "2" - runtime_constraints: - docker_image: arvados/apitestfixture - success: true - output: ea10d51bcf88862dbcc36eb292017dfd+45 - docker_image_locator: b519d9cb706a29fc7ea24dbea2f05851+93 - state: Complete - script_parameters_digest: 174dd339d44f2b259fadbab7ebdb8df9 - -previous_job_run_with_arvados_sdk_version: - uuid: zzzzz-8i9sb-eoo0321or2dw2jg - created_at: <%= 14.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 31ce37fe365b3dc204300a3e4c396ad333ed0556 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "1" - runtime_constraints: - arvados_sdk_version: commit2 - docker_image: arvados/apitestfixture - arvados_sdk_version: 00634b2b8a492d6f121e3cf1d6587b821136a9a7 - docker_image_locator: fa3c1a9cb6783f85f2ecda037e07b8c3+167 - success: true - output: ea10d51bcf88862dbcc36eb292017dfd+45 - state: Complete - script_parameters_digest: a5f03bbfb8ba88a2efe4a7852671605b - log: ea10d51bcf88862dbcc36eb292017dfd+45 - -previous_job_run_no_output: - uuid: zzzzz-8i9sb-cjs4pklxxjykppp - created_at: <%= 14.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "2" - success: true - output: ~ - state: Complete - script_parameters_digest: 174dd339d44f2b259fadbab7ebdb8df9 - -previous_job_run_superseded_by_hash_branch: - # This supplied_script_version is a branch name with later commits. - uuid: zzzzz-8i9sb-aeviezu5dahph3e - created_at: <%= 15.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/shabranchnames - script: testscript - script_version: 7387838c69a21827834586cc42b467ff6c63293b - supplied_script_version: 738783 - script_parameters: {} - success: true - output: d41d8cd98f00b204e9800998ecf8427e+0 - state: Complete - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -nondeterminisic_job_run: - uuid: zzzzz-8i9sb-cjs4pklxxjykyyy - created_at: <%= 14.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: hash2 - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - an_integer: "1" - success: true - nondeterministic: true - state: Complete - script_parameters_digest: a5f03bbfb8ba88a2efe4a7852671605b - -nearly_finished_job: - uuid: zzzzz-8i9sb-2gx6rz0pjl033w3 - created_at: <%= 14.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: arvados - script: doesnotexist - script_version: 309e25a64fe994867db8459543af372f850e25b9 - script_parameters: - input: b519d9cb706a29fc7ea24dbea2f05851+249025 - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: ~ - running: true - success: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 1 - done: 0 - runtime_constraints: {} - state: Complete - script_parameters_digest: 7ea26d58a79b7f5db9f90fb1e33d3006 - -queued: - uuid: zzzzz-8i9sb-grx15v5mjnsyxk7 - created_at: <%= 1.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - started_at: ~ - finished_at: ~ - script: foo - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters: {} - running: ~ - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: ~ - tasks_summary: {} - runtime_constraints: {} - state: Queued - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -# A job with a log collection that can be parsed by the log viewer. -job_with_real_log: - uuid: zzzzz-8i9sb-0vsrcqi7whchuil - created_at: 2014-09-01 12:00:00 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - log: 0b9a7787660e1fce4a93f33e01376ba6+81 - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - state: Complete - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -cancelled: - uuid: zzzzz-8i9sb-4cf0abc123e809j - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: <%= 1.minute.ago.to_fs(:db) %> - cancelled_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - created_at: <%= 4.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: ~ - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - running: false - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Cancelled - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -job_in_subproject: - uuid: zzzzz-8i9sb-subprojectjob01 - created_at: 2014-10-15 12:00:00 - owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x - log: ~ - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -job_in_trashed_project: - uuid: zzzzz-8i9sb-subprojectjob02 - created_at: 2014-10-15 12:00:00 - owner_uuid: zzzzz-j7d0g-trashedproject2 - log: ~ - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -running_will_be_completed: - uuid: zzzzz-8i9sb-rshmckwoma9pjh8 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 3.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: ~ - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-d9tiejq69daie8f - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -graph_stage1: - uuid: zzzzz-8i9sb-graphstage10000 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - repository: active/foo - script: hash - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - output: fa7aeb5140e2848d39b416daeef4ffc5+45 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -graph_stage2: - uuid: zzzzz-8i9sb-graphstage20000 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - repository: active/foo - script: hash2 - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - input2: "stuff" - output: 65b17c95fdbc9800fc48acda4e9dcd0b+93 - script_parameters_digest: 4900033ec5cfaf8a63566f3664aeaa70 - -graph_stage3: - uuid: zzzzz-8i9sb-graphstage30000 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - repository: active/foo - script: hash2 - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - input2: "stuff2" - output: ea10d51bcf88862dbcc36eb292017dfd+45 - script_parameters_digest: 02a085407e751d00b5dc88f1bd5e8247 - -job_with_latest_version: - uuid: zzzzz-8i9sb-nj8ioxnrvjtyk2b - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - script: hash - repository: active/foo - script_version: 7def43a4d3f20789dda4700f703b5514cc3ed250 - supplied_script_version: main - script_parameters: - input: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45 - created_at: <%= 3.minute.ago.to_fs(:db) %> - started_at: <%= 2.minute.ago.to_fs(:db) %> - finished_at: <%= 1.minute.ago.to_fs(:db) %> - running: false - success: true - output: fa7aeb5140e2848d39b416daeef4ffc5+45 - priority: 0 - log: ea10d51bcf88862dbcc36eb292017dfd+45 - is_locked_by_uuid: ~ - tasks_summary: - failed: 0 - todo: 0 - running: 0 - done: 1 - runtime_constraints: {} - state: Complete - script_parameters_digest: 03a43a7d84f7fb022467b876c2950acd - -running_job_in_publicly_accessible_project: - uuid: zzzzz-8i9sb-n7omg50bvt0m1nf - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/bar - script: running_job_script - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Running - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - input2: "stuff2" - script_parameters_digest: 02a085407e751d00b5dc88f1bd5e8247 - -completed_job_in_publicly_accessible_project: - uuid: zzzzz-8i9sb-jyq01m7in1jlofj - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: completed_job_script - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - input2: "stuff2" - log: zzzzz-4zz18-4en62shvi99lxd4 - output: b519d9cb706a29fc7ea24dbea2f05851+93 - script_parameters_digest: 02a085407e751d00b5dc88f1bd5e8247 - started_at: <%= 10.minute.ago.to_fs(:db) %> - finished_at: <%= 5.minute.ago.to_fs(:db) %> - -job_in_publicly_accessible_project_but_other_objects_elsewhere: - uuid: zzzzz-8i9sb-jyq01muyhgr4ofj - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - repository: active/foo - script: completed_job_script - script_version: 4fe459abe02d9b365932b8f5dc419439ab4e2577 - state: Complete - script_parameters: - input: fa7aeb5140e2848d39b416daeef4ffc5+45 - input2: "stuff2" - log: zzzzz-4zz18-fy296fx3hot09f7 - output: zzzzz-4zz18-bv31uwvy3neko21 - script_parameters_digest: 02a085407e751d00b5dc88f1bd5e8247 - -running_job_with_components: - uuid: zzzzz-8i9sb-with2components - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 3.minute.ago.to_fs(:db) %> - started_at: <%= 3.minute.ago.to_fs(:db) %> - finished_at: ~ - script: hash - repository: active/foo - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - components: - component1: zzzzz-8i9sb-jyq01m7in1jlofj - component2: zzzzz-d1hrv-partdonepipelin - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - -# This main level job is in running state with one job and one pipeline instance components -running_job_with_components_at_level_1: - uuid: zzzzz-8i9sb-jobcomponentsl1 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - components: - component1: zzzzz-8i9sb-jobcomponentsl2 - component2: zzzzz-d1hrv-picomponentsl02 - -# This running job, a child of level_1, has one child component -running_job_with_components_at_level_2: - uuid: zzzzz-8i9sb-jobcomponentsl2 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - components: - component1: zzzzz-8i9sb-job1atlevel3noc - -# The below two running jobs, children of level_2, have no child components -running_job_1_with_components_at_level_3: - uuid: zzzzz-8i9sb-job1atlevel3noc - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - -running_job_2_with_components_at_level_3: - uuid: zzzzz-8i9sb-job2atlevel3noc - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - -# The two jobs below are so confused, they have circular relationship -running_job_1_with_circular_component_relationship: - uuid: zzzzz-8i9sb-job1withcirculr - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - components: - component1: zzzzz-8i9sb-job2withcirculr - -running_job_2_with_circular_component_relationship: - uuid: zzzzz-8i9sb-job2withcirculr - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - cancelled_at: ~ - cancelled_by_user_uuid: ~ - cancelled_by_client_uuid: ~ - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - finished_at: ~ - repository: active/foo - script: hash - script_version: 1de84a854e2b440dc53bf42f8548afa4c17da332 - script_parameters_digest: 99914b932bd37a50b983c5e7c90ae93b - running: true - success: ~ - output: ~ - priority: 0 - log: ~ - is_locked_by_uuid: zzzzz-tpzed-xurymjxw79nv3jz - tasks_summary: - failed: 0 - todo: 3 - running: 1 - done: 1 - runtime_constraints: {} - state: Running - components: - component1: zzzzz-8i9sb-job1withcirculr diff --git a/services/api/test/fixtures/keep_disks.yml b/services/api/test/fixtures/keep_disks.yml deleted file mode 100644 index 5cccf498af..0000000000 --- a/services/api/test/fixtures/keep_disks.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -nonfull: - uuid: zzzzz-penuu-5w2o2t1q5wy7fhn - owner_uuid: zzzzz-tpzed-d9tiejq69daie8f - node_uuid: zzzzz-7ekkf-53y36l1lu5ijveb - keep_service_uuid: zzzzz-bi6l4-6zhilxar6r8ey90 - last_read_at: <%= 1.minute.ago.to_fs(:db) %> - last_write_at: <%= 2.minute.ago.to_fs(:db) %> - last_ping_at: <%= 3.minute.ago.to_fs(:db) %> - ping_secret: z9xz2tc69dho51g1dmkdy5fnupdhsprahcwxdbjs0zms4eo6i - -full: - uuid: zzzzz-penuu-4kmq58ui07xuftx - owner_uuid: zzzzz-tpzed-d9tiejq69daie8f - node_uuid: zzzzz-7ekkf-53y36l1lu5ijveb - keep_service_uuid: zzzzz-bi6l4-6zhilxar6r8ey90 - last_read_at: <%= 1.minute.ago.to_fs(:db) %> - last_write_at: <%= 2.day.ago.to_fs(:db) %> - last_ping_at: <%= 3.minute.ago.to_fs(:db) %> - ping_secret: xx3ieejcufbjy4lli6yt5ig4e8w5l2hhgmbyzpzuq38gri6lj - -nonfull2: - uuid: zzzzz-penuu-1ydrih9k2er5j11 - owner_uuid: zzzzz-tpzed-d9tiejq69daie8f - node_uuid: zzzzz-7ekkf-2z3mc76g2q73aio - keep_service_uuid: zzzzz-bi6l4-rsnj3c76ndxb7o0 - last_read_at: <%= 1.minute.ago.to_fs(:db) %> - last_write_at: <%= 2.minute.ago.to_fs(:db) %> - last_ping_at: <%= 3.minute.ago.to_fs(:db) %> - ping_secret: 4rs260ibhdum1d242xy23qv320rlerc0j7qg9vyqnchbgmjeek diff --git a/services/api/test/fixtures/links.yml b/services/api/test/fixtures/links.yml index 00d5971534..61ad60451d 100644 --- a/services/api/test/fixtures/links.yml +++ b/services/api/test/fixtures/links.yml @@ -254,104 +254,6 @@ baz_file_publicly_readable: head_uuid: zzzzz-4zz18-y9vne9npefyxh8g properties: {} -barbaz_job_readable_by_spectator: - uuid: zzzzz-o0j2j-cpy7p41hpk531e1 - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-01-24 20:42:26 -0800 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-01-24 20:42:26 -0800 - updated_at: 2014-01-24 20:42:26 -0800 - tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r - link_class: permission - name: can_read - head_uuid: zzzzz-8i9sb-cjs4pklxxjykyuq - properties: {} - -runningbarbaz_job_readable_by_spectator: - uuid: zzzzz-o0j2j-cpy7p41hpk531e2 - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-01-24 20:42:26 -0800 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-01-24 20:42:26 -0800 - updated_at: 2014-01-24 20:42:26 -0800 - tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r - link_class: permission - name: can_read - head_uuid: zzzzz-8i9sb-cjs4pklxxjykyuj - properties: {} - -arvados_repository_readable_by_all_users: - uuid: zzzzz-o0j2j-allcanreadarvrp - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-01-24 20:42:26 -0800 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-01-24 20:42:26 -0800 - updated_at: 2014-01-24 20:42:26 -0800 - tail_uuid: zzzzz-j7d0g-fffffffffffffff - link_class: permission - name: can_read - head_uuid: zzzzz-s0uqq-arvadosrepo0123 - properties: {} - -foo_repository_readable_by_spectator: - uuid: zzzzz-o0j2j-cpy7p41hpk5xxx - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-01-24 20:42:26 -0800 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-01-24 20:42:26 -0800 - updated_at: 2014-01-24 20:42:26 -0800 - tail_uuid: zzzzz-tpzed-l1s2piq4t4mps8r - link_class: permission - name: can_read - head_uuid: zzzzz-s0uqq-382brsig8rp3666 - properties: {} - -foo_repository_manageable_by_active: - uuid: zzzzz-o0j2j-8tdfjd8g0s4rn1k - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-01-24 20:42:26 -0800 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-01-24 20:42:26 -0800 - updated_at: 2014-01-24 20:42:26 -0800 - tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz - link_class: permission - name: can_manage - head_uuid: zzzzz-s0uqq-382brsig8rp3666 - properties: {} - -repository3_readable_by_active: - uuid: zzzzz-o0j2j-43iem9bdtefa76g - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-09-23 13:52:46 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-09-23 13:52:46 -0400 - updated_at: 2014-09-23 13:52:46 -0400 - tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz - link_class: permission - name: can_read - head_uuid: zzzzz-s0uqq-38orljkqpyo1j61 - properties: {} - -repository4_writable_by_active: - uuid: zzzzz-o0j2j-lio9debdt6yhkil - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-09-23 13:52:46 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-09-23 13:52:46 -0400 - updated_at: 2014-09-23 13:52:46 -0400 - tail_uuid: zzzzz-tpzed-xurymjxw79nv3jz - link_class: permission - name: can_write - head_uuid: zzzzz-s0uqq-38oru8hnk57ht34 - properties: {} - miniadmin_user_is_a_testusergroup_admin: uuid: zzzzz-o0j2j-38vvkciz7qc12j9 owner_uuid: zzzzz-tpzed-000000000000000 @@ -784,81 +686,6 @@ docker_image_tag_like_hash: properties: image_timestamp: "2014-06-10T14:30:00.184019565Z" -job_reader_can_read_previous_job_run: - # Permission link giving job_reader permission - # to read previous_job_run - uuid: zzzzz-o0j2j-8bbd851795ebafd - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-06-13 20:42:26 -0800 - modified_by_client_uuid: zzzzz-tpzed-000000000000000 - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-06-13 20:42:26 -0800 - updated_at: 2014-06-13 20:42:26 -0800 - link_class: permission - name: can_read - tail_uuid: zzzzz-tpzed-905b42d1dd4a354 - head_uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - -job_reader_can_read_foo_repo: - # Permission link giving job_reader permission - # to read foo_repo - uuid: zzzzz-o0j2j-072ec05dc9487f8 - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-06-13 20:42:26 -0800 - modified_by_client_uuid: zzzzz-tpzed-000000000000000 - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-06-13 20:42:26 -0800 - updated_at: 2014-06-13 20:42:26 -0800 - link_class: permission - name: can_read - tail_uuid: zzzzz-tpzed-905b42d1dd4a354 - head_uuid: zzzzz-s0uqq-382brsig8rp3666 - -job_reader2_can_read_job_with_components: - # Permission link giving job_reader2 permission - # to read running_job_with_components - uuid: zzzzz-o0j2j-jobcomps4jobrdr - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-06-13 20:42:26 -0800 - modified_by_client_uuid: zzzzz-tpzed-000000000000000 - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-06-13 20:42:26 -0800 - updated_at: 2014-06-13 20:42:26 -0800 - link_class: permission - name: can_read - tail_uuid: zzzzz-tpzed-readjobwithcomp - head_uuid: zzzzz-8i9sb-with2components - -job_reader2_can_read_pipeline_from_job_with_components: - # Permission link giving job_reader2 permission - # to read running_job_with_components - uuid: zzzzz-o0j2j-pi4comps4jobrdr - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-06-13 20:42:26 -0800 - modified_by_client_uuid: zzzzz-tpzed-000000000000000 - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-06-13 20:42:26 -0800 - updated_at: 2014-06-13 20:42:26 -0800 - link_class: permission - name: can_read - tail_uuid: zzzzz-tpzed-readjobwithcomp - head_uuid: zzzzz-d1hrv-partdonepipelin - -job_reader2_can_read_first_job_from_pipeline_from_job_with_components: - # Permission link giving job_reader2 permission - # to read running_job_with_components - uuid: zzzzz-o0j2j-job4pi4j4jobrdr - owner_uuid: zzzzz-tpzed-000000000000000 - created_at: 2014-06-13 20:42:26 -0800 - modified_by_client_uuid: zzzzz-tpzed-000000000000000 - modified_by_user_uuid: zzzzz-tpzed-000000000000000 - modified_at: 2014-06-13 20:42:26 -0800 - updated_at: 2014-06-13 20:42:26 -0800 - link_class: permission - name: can_read - tail_uuid: zzzzz-tpzed-readjobwithcomp - head_uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - baz_collection_name_in_asubproject: uuid: zzzzz-o0j2j-bazprojectname2 owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz diff --git a/services/api/test/fixtures/logs.yml b/services/api/test/fixtures/logs.yml index 3b41550ae7..ee24d2ac64 100644 --- a/services/api/test/fixtures/logs.yml +++ b/services/api/test/fixtures/logs.yml @@ -11,22 +11,22 @@ noop: # nothing happened ...to the 'spectator' user event_at: <%= 1.minute.ago.to_fs(:db) %> created_at: <%= 1.minute.ago.to_fs(:db) %> -admin_changes_repository2: # admin changes repository2, which is owned by active user +admin_changes_collection_owned_by_active: id: 2 uuid: zzzzz-57u5n-pshmckwoma00002 owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user - object_uuid: zzzzz-2x53u-382brsig8rp3667 # repository foo + object_uuid: zzzzz-4zz18-bv31uwvy3neko21 # collection_owned_by_active object_owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user created_at: <%= 2.minute.ago.to_fs(:db) %> event_at: <%= 2.minute.ago.to_fs(:db) %> event_type: update -admin_changes_specimen: # admin changes specimen owned_by_spectator +admin_changes_collection_owned_by_foo: id: 3 uuid: zzzzz-57u5n-pshmckwoma00003 owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user - object_uuid: zzzzz-2x53u-3b0xxwzlbzxq5yr # specimen owned_by_spectator - object_owner_uuid: zzzzz-tpzed-l1s2piq4t4mps8r # spectator user + object_uuid: zzzzz-4zz18-50surkhkbhsp31b # collection_owned_by_foo + object_owner_uuid: zzzzz-tpzed-81hsbo6mk8nl05c # foo user created_at: <%= 3.minute.ago.to_fs(:db) %> event_at: <%= 3.minute.ago.to_fs(:db) %> event_type: update @@ -60,101 +60,6 @@ log_owned_by_active: event_at: <%= 2.minute.ago.to_fs(:db) %> summary: non-admin use can read own logs -crunchstat_for_running_job: - id: 7 - uuid: zzzzz-57u5n-tmymyrojrbtnxh1 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - modified_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - object_uuid: zzzzz-8i9sb-pshmckwoma9plh7 - event_at: 2014-11-07 23:33:42.347455000 Z - event_type: stderr - summary: ~ - properties: - text: '2014-11-07_23:33:41 zzzzz-8i9sb-pshmckwoma9plh7 31708 1 stderr crunchstat: - cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user - 0.9900 sys' - created_at: 2014-11-07 23:33:42.351913000 Z - updated_at: 2014-11-07 23:33:42.347455000 Z - modified_at: 2014-11-07 23:33:42.347455000 Z - object_owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - -log_line_for_pipeline_in_publicly_accessible_project: - id: 8 - uuid: zzzzz-57u5n-tmymyrojrjyhb45 - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - modified_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - object_uuid: zzzzz-d1hrv-n68vc490mloy4fi - event_at: 2014-11-07 23:33:42.347455000 Z - event_type: stderr - summary: ~ - properties: - text: '2014-11-07_23:33:41 zzzzz-d1hrv-n68vc490mloy4fi 31708 1 stderr crunchstat: - cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user - 0.9900 sys' - created_at: 2014-11-07 23:33:42.351913000 Z - updated_at: 2014-11-07 23:33:42.347455000 Z - modified_at: 2014-11-07 23:33:42.347455000 Z - object_owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - -log_line_for_pipeline_in_publicly_accessible_project_but_other_objects_elsewhere: - id: 9 - uuid: zzzzz-57u5n-tmyhy56k9lnhb45 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - modified_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - object_uuid: zzzzz-d1hrv-pisharednotobjs - event_at: 2014-11-07 23:33:42.347455000 Z - event_type: stderr - summary: ~ - properties: - text: '2014-11-07_23:33:41 zzzzz-d1hrv-pisharednotobjs 31708 1 stderr crunchstat: - cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user - 0.9900 sys' - created_at: 2014-11-07 23:33:42.351913000 Z - updated_at: 2014-11-07 23:33:42.347455000 Z - modified_at: 2014-11-07 23:33:42.347455000 Z - object_owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - -crunchstat_for_previous_job: - id: 10 - uuid: zzzzz-57u5n-eir3aesha3kaene - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - modified_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - object_uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - event_at: 2014-11-07 23:33:42.347455000 Z - event_type: stderr - summary: ~ - properties: - text: '2014-11-07_23:33:41 zzzzz-8i9sb-cjs4pklxxjykqqq 11592 1 stderr crunchstat: - cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user - 0.9900 sys' - created_at: 2014-11-07 23:33:42.351913000 Z - updated_at: 2014-11-07 23:33:42.347455000 Z - modified_at: 2014-11-07 23:33:42.347455000 Z - object_owner_uuid: zzzzz-j7d0g-xurymjxw79nv3jz - -crunchstat_for_ancient_job: - id: 11 - uuid: zzzzz-57u5n-ixioph7ieb5ung8 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - modified_by_client_uuid: zzzzz-ozdt8-obw7foaks3qjyej - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - object_uuid: zzzzz-8i9sb-ahd7cie8jah9qui - event_at: 2013-11-07 23:33:42.347455000 Z - event_type: stderr - summary: ~ - properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: - cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user - 0.9900 sys' - created_at: 2013-11-07 23:33:42.351913000 Z - updated_at: 2013-11-07 23:33:42.347455000 Z - modified_at: 2013-11-07 23:33:42.347455000 Z - object_owner_uuid: zzzzz-j7d0g-xurymjxw79nv3jz - stderr_for_ancient_container: id: 12 uuid: zzzzz-57u5n-containerlog001 @@ -166,7 +71,7 @@ stderr_for_ancient_container: event_type: stderr summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer01 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 2.year.ago.to_fs(:db) %> @@ -185,7 +90,7 @@ crunchstat_for_ancient_container: event_type: crunchstat summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer01 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 2.year.ago.to_fs(:db) %> @@ -204,7 +109,7 @@ stderr_for_previous_container: event_type: stderr summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer02 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 1.month.ago.to_fs(:db) %> @@ -223,7 +128,7 @@ crunchstat_for_previous_container: event_type: crunchstat summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer02 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 1.month.ago.to_fs(:db) %> @@ -242,7 +147,7 @@ stderr_for_running_container: event_type: crunchstat summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer03 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 1.hour.ago.to_fs(:db) %> @@ -261,7 +166,7 @@ crunchstat_for_running_container: event_type: crunchstat summary: ~ properties: - text: '2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: + text: '2013-11-07_23:33:41 zzzzz-dz642-logscontainer03 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys' created_at: <%= 1.hour.ago.to_fs(:db) %> diff --git a/services/api/test/fixtures/nodes.yml b/services/api/test/fixtures/nodes.yml deleted file mode 100644 index d4589ed705..0000000000 --- a/services/api/test/fixtures/nodes.yml +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -busy: - uuid: zzzzz-7ekkf-53y36l1lu5ijveb - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: compute0 - slot_number: 0 - domain: "" - ip_address: 172.17.2.172 - last_ping_at: <%= 1.minute.ago.to_fs(:db) %> - first_ping_at: <%= 23.hour.ago.to_fs(:db) %> - job_uuid: zzzzz-8i9sb-2gx6rz0pjl033w3 # nearly_finished_job - properties: {} - info: - ping_secret: "48dpm3b8ijyj3jkr2yczxw0844dqd2752bhll7klodvgz9bg80" - slurm_state: "alloc" - -down: - uuid: zzzzz-7ekkf-2vbompg3ecc6e2s - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: compute1 - slot_number: 1 - domain: "" - ip_address: 172.17.2.173 - last_ping_at: <%= 1.hour.ago.to_fs(:db) %> - first_ping_at: <%= 23.hour.ago.to_fs(:db) %> - job_uuid: ~ - properties: {} - info: - ping_secret: "2k3i71depad36ugwmlgzilbi4e8n0illb2r8l4efg9mzkb3a1k" - -idle: - uuid: zzzzz-7ekkf-2z3mc76g2q73aio - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: compute2 - slot_number: 2 - domain: "" - ip_address: 172.17.2.174 - last_ping_at: <%= 2.minute.ago.to_fs(:db) %> - first_ping_at: <%= 23.hour.ago.to_fs(:db) %> - job_uuid: ~ - info: - ping_secret: "69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0" - slurm_state: "idle" - properties: - total_cpu_cores: 16 - -was_idle_now_down: - uuid: zzzzz-7ekkf-xuzpkdasl0uzwyz - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: compute3 - slot_number: ~ - domain: "" - ip_address: 172.17.2.174 - last_ping_at: <%= 1.hour.ago.to_fs(:db) %> - first_ping_at: <%= 23.hour.ago.to_fs(:db) %> - job_uuid: ~ - info: - ping_secret: "1bd1yi0x4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2" - slurm_state: "idle" - properties: - total_cpu_cores: 16 - -new_with_no_hostname: - uuid: zzzzz-7ekkf-newnohostname00 - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: ~ - slot_number: ~ - ip_address: 172.17.2.175 - last_ping_at: ~ - first_ping_at: ~ - job_uuid: ~ - properties: {} - info: - ping_secret: "abcdyi0x4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2" - -new_with_custom_hostname: - uuid: zzzzz-7ekkf-newwithhostname - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: custom1 - slot_number: 23 - ip_address: 172.17.2.176 - last_ping_at: ~ - first_ping_at: ~ - job_uuid: ~ - properties: {} - info: - ping_secret: "abcdyi0x4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2" - -node_with_no_ip_address_yet: - uuid: zzzzz-7ekkf-nodenoipaddryet - owner_uuid: zzzzz-tpzed-000000000000000 - hostname: noipaddr - slot_number: ~ - last_ping_at: ~ - first_ping_at: ~ - job_uuid: ~ - properties: {} - info: - ping_secret: "abcdyefg4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2" diff --git a/services/api/test/fixtures/pipeline_instances.yml b/services/api/test/fixtures/pipeline_instances.yml deleted file mode 100644 index 714fc60771..0000000000 --- a/services/api/test/fixtures/pipeline_instances.yml +++ /dev/null @@ -1,530 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -new_pipeline: - state: New - uuid: zzzzz-d1hrv-f4gneyn6br1xize - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 1.minute.ago.to_fs(:db) %> - -new_pipeline_in_subproject: - state: New - uuid: zzzzz-d1hrv-subprojpipeline - owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x - created_at: <%= 1.minute.ago.to_fs(:db) %> - -has_component_with_no_script_parameters: - state: Ready - uuid: zzzzz-d1hrv-1xfj6xkicf2muk2 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 10.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: {} - -has_component_with_empty_script_parameters: - state: Ready - uuid: zzzzz-d1hrv-jq16l10gcsnyumo - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 3.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - -has_component_with_completed_jobs: - # Test that the job "started_at" and "finished_at" fields are parsed - # into Time fields when rendering. These jobs must *not* have their - # own fixtures; the point is to force the - # pipeline_instances_controller_test in Workbench to parse the - # "components" field. (The relevant code paths are also used when a - # user has permission to read the pipeline instance itself, but not - # the jobs referenced by its components hash.) - state: Complete - uuid: zzzzz-d1hrv-i3e77t9z5y8j9cc - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 11.minute.ago.to_fs(:db) %> - started_at: <%= 10.minute.ago.to_fs(:db) %> - finished_at: <%= 9.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-rft1xdewxkwgxnz - script_version: main - created_at: <%= 10.minute.ago.to_fs(:db) %> - started_at: <%= 10.minute.ago.to_fs(:db) %> - finished_at: <%= 9.minute.ago.to_fs(:db) %> - state: Complete - tasks_summary: - failed: 0 - todo: 0 - running: 0 - done: 1 - bar: - script: bar - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-r2dtbzr6bfread7 - script_version: main - created_at: <%= 9.minute.ago.to_fs(:db) %> - started_at: <%= 9.minute.ago.to_fs(:db) %> - state: Running - tasks_summary: - failed: 0 - todo: 1 - running: 2 - done: 3 - baz: - script: baz - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-c7408rni11o7r6s - script_version: main - created_at: <%= 9.minute.ago.to_fs(:db) %> - state: Queued - tasks_summary: {} - -has_job: - name: pipeline_with_job - state: Ready - uuid: zzzzz-d1hrv-1yfj6xkidf2muk3 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 2.9.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: {} - job: { - uuid: zzzzz-8i9sb-pshmckwoma9plh7, - script_version: main - } - -components_is_jobspec: - # Helps test that clients cope with funny-shaped components. - # For an example, see #3321. - uuid: zzzzz-d1hrv-1yfj61234abcdk4 - created_at: <%= 4.minute.ago.to_fs(:db) %> - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - state: RunningOnServer - components: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - -pipeline_with_tagged_collection_input: - name: pipeline_with_tagged_collection_input - state: Ready - uuid: zzzzz-d1hrv-1yfj61234abcdk3 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 3.2.minute.ago.to_fs(:db) %> - components: - part-one: - script_parameters: - input: - value: zzzzz-4zz18-znfnqtbbv4spc3w - -pipeline_to_merge_params: - name: pipeline_to_merge_params - state: Ready - uuid: zzzzz-d1hrv-1yfj6dcba4321k3 - pipeline_template_uuid: zzzzz-p5p6p-aox0k0ofxrystgw - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 3.3.minute.ago.to_fs(:db) %> - components: - part-one: - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - part-two: - script_parameters: - input: - output_of: part-one - integer_with_default: - default: 123 - integer_with_value: - value: 123 - string_with_default: - default: baz - string_with_value: - value: baz - plain_string: qux - array_with_default: - default: [1,1,2,3,5] - array_with_value: - value: [1,1,2,3,5] - -pipeline_with_newer_template: - state: Complete - uuid: zzzzz-d1hrv-9fm8l10i9z2kqc6 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - pipeline_template_uuid: zzzzz-p5p6p-vq4wuvy84xvaq2r - created_at: 2014-09-15 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - -pipeline_instance_owned_by_fuse: - state: Complete - uuid: zzzzz-d1hrv-ri9dvgkgqs9y09j - owner_uuid: zzzzz-tpzed-0fusedrivertest - pipeline_template_uuid: zzzzz-p5p6p-vq4wuvy84xvaq2r - created_at: 2014-09-16 12:00:00 - name: "pipeline instance owned by FUSE" - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - -pipeline_instance_in_fuse_project: - state: Complete - uuid: zzzzz-d1hrv-scarxiyajtshq3l - owner_uuid: zzzzz-j7d0g-0000ownedbyfuse - pipeline_template_uuid: zzzzz-p5p6p-vq4wuvy84xvaq2r - created_at: 2014-09-17 12:00:00 - name: "pipeline instance in FUSE project" - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - -pipeline_owned_by_active_in_aproject: - name: Completed pipeline in A Project - state: Complete - uuid: zzzzz-d1hrv-ju5ghi0i9z2kqc6 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-09-18 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - -pipeline_owned_by_active_in_home: - name: Completed pipeline in active user home - state: Complete - uuid: zzzzz-d1hrv-lihrbd0i9z2kqc6 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-09-19 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - -pipeline_in_publicly_accessible_project: - uuid: zzzzz-d1hrv-n68vc490mloy4fi - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - name: Pipeline in publicly accessible project - pipeline_template_uuid: zzzzz-p5p6p-tmpltpublicproj - state: Complete - created_at: <%= 30.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - job: - uuid: zzzzz-8i9sb-jyq01m7in1jlofj - repository: active/foo - script: foo - script_version: main - script_parameters: - input: zzzzz-4zz18-4en62shvi99lxd4 - log: zzzzz-4zz18-4en62shvi99lxd4 - output: b519d9cb706a29fc7ea24dbea2f05851+93 - state: Complete - -pipeline_in_publicly_accessible_project_but_other_objects_elsewhere: - uuid: zzzzz-d1hrv-pisharednotobjs - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - name: Pipeline in public project with other objects elsewhere - pipeline_template_uuid: zzzzz-p5p6p-aox0k0ofxrystgw - state: Complete - created_at: 2014-09-20 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - job: - uuid: zzzzz-8i9sb-aceg2bnq7jt7kon - repository: active/foo - script: foo - script_version: main - script_parameters: - input: zzzzz-4zz18-bv31uwvy3neko21 - log: zzzzz-4zz18-bv31uwvy3neko21 - output: zzzzz-4zz18-bv31uwvy3neko21 - state: Complete - -new_pipeline_in_publicly_accessible_project: - uuid: zzzzz-d1hrv-newpisharedobjs - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - name: Pipeline in New state in publicly accessible project - pipeline_template_uuid: zzzzz-p5p6p-tmpltpublicproj - state: New - created_at: 2014-09-21 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - value: b519d9cb706a29fc7ea24dbea2f05851+93 - -new_pipeline_in_publicly_accessible_project_but_other_objects_elsewhere: - uuid: zzzzz-d1hrv-newsharenotobjs - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - name: Pipeline in New state in public project with objects elsewhere - pipeline_template_uuid: zzzzz-p5p6p-aox0k0ofxrystgw - state: New - created_at: 2014-09-22 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - value: zzzzz-4zz18-bv31uwvy3neko21 - -new_pipeline_in_publicly_accessible_project_with_dataclass_file_and_other_objects_elsewhere: - uuid: zzzzz-d1hrv-newsharenotfile - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - name: Pipeline in public project in New state with file type data class with objects elsewhere - pipeline_template_uuid: zzzzz-p5p6p-aox0k0ofxrystgw - state: New - created_at: 2014-09-23 12:00:00 - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: File - value: zzzzz-4zz18-bv31uwvy3neko21/bar - -pipeline_in_running_state: - name: running_with_job - uuid: zzzzz-d1hrv-runningpipeline - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 2.8.minute.ago.to_fs(:db) %> - started_at: <%= 2.8.minute.ago.to_fs(:db) %> - state: RunningOnServer - components: - foo: - script: foo - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-pshmckwoma9plh7 - script_version: main - -running_pipeline_with_complete_job: - uuid: zzzzz-d1hrv-partdonepipelin - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - state: RunningOnServer - created_at: <%= 15.minute.ago.to_fs(:db) %> - components: - previous: - job: - uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - log: zzzzz-4zz18-op4e2lbej01tcvu - running: - job: - uuid: zzzzz-8i9sb-pshmckwoma9plh7 - -complete_pipeline_with_two_jobs: - uuid: zzzzz-d1hrv-twodonepipeline - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - state: Complete - created_at: <%= 2.5.minute.ago.to_fs(:db) %> - started_at: <%= 2.minute.ago.to_fs(:db) %> - finished_at: <%= 1.minute.ago.to_fs(:db) %> - components: - ancient: - job: - uuid: zzzzz-8i9sb-ahd7cie8jah9qui - log: zzzzz-4zz18-op4e2lbej01tcvu - previous: - job: - uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - log: zzzzz-4zz18-op4e2lbej01tcvu - -failed_pipeline_with_two_jobs: - uuid: zzzzz-d1hrv-twofailpipeline - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 55.minute.ago.to_fs(:db) %> - state: Failed - components: - ancient: - job: - uuid: zzzzz-8i9sb-ahd7cie8jah9qui - log: zzzzz-4zz18-op4e2lbej01tcvu - previous: - job: - uuid: zzzzz-8i9sb-cjs4pklxxjykqqq - log: zzzzz-4zz18-op4e2lbej01tcvu - -# This pipeline is a child of another running job and has it's own running children -job_child_pipeline_with_components_at_level_2: - state: RunningOnServer - uuid: zzzzz-d1hrv-picomponentsl02 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-job1atlevel3noc - script_version: main - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - state: Running - tasks_summary: - failed: 0 - todo: 0 - running: 1 - done: 1 - bar: - script: bar - script_version: main - script_parameters: {} - job: - uuid: zzzzz-8i9sb-job2atlevel3noc - script_version: main - created_at: <%= 12.hour.ago.to_fs(:db) %> - started_at: <%= 12.hour.ago.to_fs(:db) %> - state: Running - tasks_summary: - failed: 0 - todo: 1 - running: 2 - done: 3 - -# Test Helper trims the rest of the file - -# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper - -# pipelines in project_with_10_pipelines -<% for i in 1..10 do %> -pipeline_<%=i%>_of_10: - name: pipeline_<%= i %> - uuid: zzzzz-d1hrv-10pipelines0<%= i.to_s.rjust(3, '0') %> - owner_uuid: zzzzz-j7d0g-000010pipelines - created_at: <%= (2*(i-1)).hour.ago.to_fs(:db) %> - started_at: <%= (2*(i-1)).hour.ago.to_fs(:db) %> - finished_at: <%= (i-1).minute.ago.to_fs(:db) %> - state: Failed - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input - job: - state: Failed -<% end %> - -# pipelines in project_with_2_pipelines_and_60_crs -<% for i in 1..2 do %> -pipeline_<%=i%>_of_2_pipelines_and_60_crs: - name: pipeline_<%= i %> - state: New - uuid: zzzzz-d1hrv-abcgneyn6brx<%= i.to_s.rjust(3, '0') %> - owner_uuid: zzzzz-j7d0g-nnncrspipelines - created_at: <%= i.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input -<% end %> - -# pipelines in project_with_25_pipelines -<% for i in 1..25 do %> -pipeline_<%=i%>_of_25: - name: pipeline_<%=i%> - state: Failed - uuid: zzzzz-d1hrv-25pipelines0<%= i.to_s.rjust(3, '0') %> - owner_uuid: zzzzz-j7d0g-000025pipelines - created_at: <%= i.hour.ago.to_fs(:db) %> - started_at: <%= i.hour.ago.to_fs(:db) %> - finished_at: <%= i.minute.ago.to_fs(:db) %> - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo instance input -<% end %> - -# Do not add your fixtures below this line as the rest of this file will be trimmed by test_helper diff --git a/services/api/test/fixtures/pipeline_templates.yml b/services/api/test/fixtures/pipeline_templates.yml deleted file mode 100644 index 0c185eeb80..0000000000 --- a/services/api/test/fixtures/pipeline_templates.yml +++ /dev/null @@ -1,271 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -two_part: - uuid: zzzzz-p5p6p-aox0k0ofxrystgw - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Two Part Pipeline Template - components: - part-one: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - part-two: - script: bar - script_version: main - script_parameters: - input: - output_of: part-one - integer_with_default: - default: 123 - integer_with_value: - value: 123 - string_with_default: - default: baz - string_with_value: - value: baz - plain_string: qux - array_with_default: # important to test repeating values in the array! - default: [1,1,2,3,5] - array_with_value: # important to test repeating values in the array! - value: [1,1,2,3,5] - -components_is_jobspec: - # Helps test that clients cope with funny-shaped components. - # For an example, see #3321. - uuid: zzzzz-p5p6p-jobspeccomponts - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Pipeline Template with Jobspec Components - components: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - -parameter_with_search: - uuid: zzzzz-p5p6p-paramwsearch345 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Pipeline Template with Input Parameter with Search - components: - with-search: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - search_for: sometime # Matches baz_collection_in_asubproject - -new_pipeline_template: - # This template must include components that are not - # present in the pipeline instance 'pipeline_with_newer_template', - # at least one of which has a script_parameter that is a hash - # with a 'dataclass' field (ticket #4000) - uuid: zzzzz-p5p6p-vq4wuvy84xvaq2r - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-09-14 12:00:00 - modified_at: 2014-09-16 12:00:00 - name: Pipeline Template Newer Than Instance - components: - foo: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: foo template input - bar: - script: bar - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: bar template input - -pipeline_template_in_fuse_project: - uuid: zzzzz-p5p6p-templinfuseproj - owner_uuid: zzzzz-j7d0g-0000ownedbyfuse - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-0fusedrivertest - name: pipeline template in FUSE project - components: - foo_component: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "default input" - description: "input collection" - -template_with_dataclass_file: - uuid: zzzzz-p5p6p-k0xoa0ofxrystgw - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Two Part Template with dataclass File - components: - part-one: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: File - title: "Foo/bar pair" - description: "Provide an input file" - part-two: - script: bar - script_version: main - script_parameters: - input: - output_of: part-one - integer_with_default: - default: 123 - integer_with_value: - value: 123 - string_with_default: - default: baz - string_with_value: - value: baz - plain_string: qux - array_with_default: # important to test repeating values in the array! - default: [1,1,2,3,5] - array_with_value: # important to test repeating values in the array! - value: [1,1,2,3,5] - -template_with_dataclass_number: - uuid: zzzzz-p5p6p-numbertemplatea - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2015-01-14 12:35:04 -0400 - updated_at: 2015-01-14 12:35:04 -0400 - modified_at: 2015-01-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Template with dataclass number - components: - work: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: number - title: "Input number" - -pipeline_template_in_publicly_accessible_project: - uuid: zzzzz-p5p6p-tmpltpublicproj - owner_uuid: zzzzz-j7d0g-zhxawtyetzwc5f0 - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Pipeline template in publicly accessible project - components: - foo_component: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "default input" - description: "input collection" - -# Used to test renaming when removed from the "aproject" subproject -# while another such object with same name exists in home project. -template_in_active_user_home_project_to_test_unique_key_violation: - uuid: zzzzz-p5p6p-templatsamenam1 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2013-04-14 12:35:04 -0400 - updated_at: 2013-04-14 12:35:04 -0400 - modified_at: 2013-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Template to test owner uuid and name unique key violation upon removal - components: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - -template_in_asubproject_with_same_name_as_one_in_active_user_home: - uuid: zzzzz-p5p6p-templatsamenam2 - owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x - created_at: 2013-04-14 12:35:04 -0400 - updated_at: 2013-04-14 12:35:04 -0400 - modified_at: 2013-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Template to test owner uuid and name unique key violation upon removal - components: - script: foo - script_version: main - script_parameters: - input: - required: true - dataclass: Collection - title: "Foo/bar pair" - description: "Provide a collection containing at least two files." - -workflow_with_input_defaults: - uuid: zzzzz-p5p6p-aox0k0ofxrystg2 - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-04-14 12:35:04 -0400 - updated_at: 2014-04-14 12:35:04 -0400 - modified_at: 2014-04-14 12:35:04 -0400 - modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr - modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz - name: Pipeline with default input specifications - components: - part-one: - script: foo - script_version: main - script_parameters: - ex_string: - required: true - dataclass: string - ex_string_def: - required: true - dataclass: string - default: hello-testing-123 diff --git a/services/api/test/fixtures/repositories.yml b/services/api/test/fixtures/repositories.yml deleted file mode 100644 index e4fe71e402..0000000000 --- a/services/api/test/fixtures/repositories.yml +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -crunch_dispatch_test: - uuid: zzzzz-s0uqq-382brsig8rp3665 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user - name: active/crunchdispatchtest - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -arvados: - uuid: zzzzz-s0uqq-arvadosrepo0123 - owner_uuid: zzzzz-tpzed-000000000000000 # root - name: arvados - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -foo: - uuid: zzzzz-s0uqq-382brsig8rp3666 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user - name: active/foo - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -repository2: - uuid: zzzzz-s0uqq-382brsig8rp3667 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user - name: active/foo2 - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -repository3: - uuid: zzzzz-s0uqq-38orljkqpyo1j61 - owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user - name: admin/foo3 - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -repository4: - uuid: zzzzz-s0uqq-38oru8hnk57ht34 - owner_uuid: zzzzz-tpzed-d9tiejq69daie8f # admin user - name: admin/foo4 - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z - -has_branch_with_commit_hash_name: - uuid: zzzzz-s0uqq-382brsig8rp3668 - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz # active user - name: active/shabranchnames - created_at: 2015-01-01T00:00:00.123456Z - modified_at: 2015-01-01T00:00:00.123456Z diff --git a/services/api/test/fixtures/specimens.yml b/services/api/test/fixtures/specimens.yml deleted file mode 100644 index bcae020812..0000000000 --- a/services/api/test/fixtures/specimens.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -owned_by_active_user: - uuid: zzzzz-j58dm-3zx463qyo0k4xrn - owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz - created_at: 2014-04-21 15:37:48 -0400 - modified_at: 2014-04-21 15:37:48 -0400 - -owned_by_private_group: - uuid: zzzzz-j58dm-5m3qwg45g3nlpu6 - owner_uuid: zzzzz-j7d0g-rew6elm53kancon - created_at: 2014-04-21 15:37:48 -0400 - modified_at: 2014-04-21 15:37:48 -0400 - -owned_by_spectator: - uuid: zzzzz-j58dm-3b0xxwzlbzxq5yr - owner_uuid: zzzzz-tpzed-l1s2piq4t4mps8r - created_at: 2014-04-21 15:37:48 -0400 - modified_at: 2014-04-21 15:37:48 -0400 - -in_aproject: - uuid: zzzzz-j58dm-7r18rnd5nzhg5yk - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-04-21 15:37:48 -0400 - modified_at: 2014-04-21 15:37:48 -0400 - -in_asubproject: - uuid: zzzzz-j58dm-c40lddwcqqr1ffs - owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x - created_at: 2014-04-21 15:37:48 -0400 - modified_at: 2014-04-21 15:37:48 -0400 diff --git a/services/api/test/fixtures/traits.yml b/services/api/test/fixtures/traits.yml deleted file mode 100644 index 83beb7087d..0000000000 --- a/services/api/test/fixtures/traits.yml +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -owned_by_aproject_with_no_name: - uuid: zzzzz-q1cn2-ypsjlol9dofwijz - owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso - created_at: 2014-05-05 04:11:52 -0400 - modified_at: 2014-05-05 04:11:52 -0400 diff --git a/services/api/test/functional/application_controller_test.rb b/services/api/test/functional/application_controller_test.rb index af7882141e..2a64e9c5e2 100644 --- a/services/api/test/functional/application_controller_test.rb +++ b/services/api/test/functional/application_controller_test.rb @@ -13,8 +13,8 @@ class ApplicationControllerTest < ActionController::TestCase setup do # These tests are meant to check behavior in ApplicationController. - # We instantiate a small concrete controller for convenience. - @controller = Arvados::V1::SpecimensController.new + # We instantiate an arbitrary concrete controller. + @controller = Arvados::V1::CollectionsController.new @start_stamp = now_timestamp end @@ -42,13 +42,13 @@ class ApplicationControllerTest < ActionController::TestCase test "requesting object without read permission returns 404 error" do authorize_with :spectator - get(:show, params: {id: specimens(:owned_by_active_user).uuid}) + get(:show, params: {id: collections(:collection_owned_by_active).uuid}) check_404 end test "submitting bad object returns error" do authorize_with :spectator - post(:create, params: {specimen: {badattr: "badvalue"}}) + post(:create, params: {collection: {badattr: "badvalue"}}) assert_response 422 check_error_token end diff --git a/services/api/test/functional/arvados/v1/collections_controller_test.rb b/services/api/test/functional/arvados/v1/collections_controller_test.rb index 43797035bc..3f65b934f5 100644 --- a/services/api/test/functional/arvados/v1/collections_controller_test.rb +++ b/services/api/test/functional/arvados/v1/collections_controller_test.rb @@ -516,14 +516,10 @@ EOS test "get full provenance for baz file" do authorize_with :active - get :provenance, params: {id: 'ea10d51bcf88862dbcc36eb292017dfd+45'} + get :provenance, params: {id: '1f4b0bc7583c2a7f9102c395f4ffc5e3+45'} assert_response :success resp = JSON.parse(@response.body) - assert_not_nil resp['ea10d51bcf88862dbcc36eb292017dfd+45'] # baz - assert_not_nil resp['fa7aeb5140e2848d39b416daeef4ffc5+45'] # bar - assert_not_nil resp['1f4b0bc7583c2a7f9102c395f4ffc5e3+45'] # foo - assert_not_nil resp['zzzzz-8i9sb-cjs4pklxxjykyuq'] # bar->baz - assert_not_nil resp['zzzzz-8i9sb-aceg2bnq7jt7kon'] # foo->bar + assert_not_nil resp['1f4b0bc7583c2a7f9102c395f4ffc5e3+45'] # baz collection end test "get no provenance for foo file" do @@ -540,10 +536,7 @@ EOS assert_response :success resp = JSON.parse(@response.body) assert_not_nil resp['ea10d51bcf88862dbcc36eb292017dfd+45'] # baz - assert_not_nil resp['fa7aeb5140e2848d39b416daeef4ffc5+45'] # bar - assert_not_nil resp['zzzzz-8i9sb-cjs4pklxxjykyuq'] # bar->baz - assert_nil resp['zzzzz-8i9sb-aceg2bnq7jt7kon'] # foo->bar - assert_nil resp['1f4b0bc7583c2a7f9102c395f4ffc5e3+45'] # foo + assert_nil resp['fa7aeb5140e2848d39b416daeef4ffc5+45'] # foo->bar end test "search collections with 'any' operator" do diff --git a/services/api/test/functional/arvados/v1/commits_controller_test.rb b/services/api/test/functional/arvados/v1/commits_controller_test.rb deleted file mode 100644 index bf285b06e0..0000000000 --- a/services/api/test/functional/arvados/v1/commits_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::CommitsControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/groups_controller_test.rb b/services/api/test/functional/arvados/v1/groups_controller_test.rb index ee7f716c80..6e167bb91e 100644 --- a/services/api/test/functional/arvados/v1/groups_controller_test.rb +++ b/services/api/test/functional/arvados/v1/groups_controller_test.rb @@ -65,12 +65,12 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase assert_equal 0, json_response['items_available'] end - def check_project_contents_response disabled_kinds=[] + def check_project_contents_response assert_response :success assert_operator 2, :<=, json_response['items_available'] assert_operator 2, :<=, json_response['items'].count kinds = json_response['items'].collect { |i| i['kind'] }.uniq - expect_kinds = %w'arvados#group arvados#specimen arvados#pipelineTemplate arvados#job' - disabled_kinds + expect_kinds = %w'arvados#group' assert_equal expect_kinds, (expect_kinds & kinds) json_response['items'].each do |i| @@ -79,10 +79,6 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase "group#contents returned a non-project group") end end - - disabled_kinds.each do |d| - assert_equal true, !kinds.include?(d) - end end test 'get group-owned objects' do @@ -107,17 +103,17 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase authorize_with :project_viewer get :contents, params: { format: :json, - filters: [['uuid', 'is_a', 'arvados#specimen']] + filters: [['uuid', 'is_a', 'arvados#collection']] } assert_response :success found_uuids = json_response['items'].collect { |i| i['uuid'] } - [[:in_aproject, true], - [:in_asubproject, true], - [:owned_by_private_group, false]].each do |specimen_fixture, should_find| + [[:foo_collection_in_aproject, true], + [:baz_collection_name_in_asubproject, true], + [:collection_not_readable_by_active, false]].each do |collection_fixture, should_find| if should_find - assert_includes found_uuids, specimens(specimen_fixture).uuid, "did not find specimen fixture '#{specimen_fixture}'" + assert_includes found_uuids, collections(collection_fixture).uuid, "did not find collection fixture '#{collection_fixture}'" else - refute_includes found_uuids, specimens(specimen_fixture).uuid, "found specimen fixture '#{specimen_fixture}'" + refute_includes found_uuids, collections(collection_fixture).uuid, "found collection fixture '#{collection_fixture}'" end end end @@ -150,8 +146,8 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase } assert_response :success found_uuids = json_response['items'].collect { |i| i['uuid'] } - assert_includes found_uuids, specimens(:owned_by_active_user).uuid, "specimen did not appear in home project" - refute_includes found_uuids, specimens(:in_asubproject).uuid, "specimen appeared unexpectedly in home project" + assert_includes found_uuids, collections(:collection_owned_by_active).uuid, "collection did not appear in home project" + refute_includes found_uuids, collections(:foo_collection_in_aproject).uuid, "collection appeared unexpectedly in home project" end test "list collections in home project" do @@ -279,20 +275,20 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase test "user with project read permission can't rename items in it" do authorize_with :project_viewer - @controller = Arvados::V1::LinksController.new + @controller = Arvados::V1::CollectionsController.new post :update, params: { - id: jobs(:running).uuid, + id: collections(:collection_to_search_for_in_aproject).uuid, name: "Denied test name", } assert_includes(403..404, response.status) end test "user with project read permission can't remove items from it" do - @controller = Arvados::V1::PipelineTemplatesController.new + @controller = Arvados::V1::CollectionsController.new authorize_with :project_viewer post :update, params: { - id: pipeline_templates(:two_part).uuid, - pipeline_template: { + id: collections(:collection_to_search_for_in_aproject).uuid, + collection: { owner_uuid: users(:project_viewer).uuid, } } @@ -339,8 +335,8 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase select: ["uuid", "storage_classes_desired"] } assert_response :success - assert_equal 17, json_response['items_available'] - assert_equal 17, json_response['items'].count + assert_equal 6, json_response['items_available'] + assert_equal 6, json_response['items'].count json_response['items'].each do |item| # Expect collections to have a storage_classes field, other items should not. if item["kind"] == "arvados#collection" @@ -480,9 +476,9 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase [ [['owner_uuid', '!=', 'zzzzz-tpzed-xurymjxw79nv3jz'], 200, - 'zzzzz-d1hrv-subprojpipeline', 'zzzzz-d1hrv-1xfj6xkicf2muk2'], - [["pipeline_instances.state", "not in", ["Complete", "Failed"]], 200, - 'zzzzz-d1hrv-1xfj6xkicf2muk2', 'zzzzz-d1hrv-i3e77t9z5y8j9cc'], + 'zzzzz-j7d0g-publicfavorites', 'zzzzz-xvhdp-cr4queuedcontnr'], + [["container_requests.state", "not in", ["Final"]], 200, + 'zzzzz-xvhdp-cr4queuedcontnr', 'zzzzz-xvhdp-cr4completedctr'], [['container_requests.requesting_container_uuid', '=', nil], 200, 'zzzzz-xvhdp-cr4queuedcontnr', 'zzzzz-xvhdp-cr4requestercn2'], [['container_requests.no_such_column', '=', nil], 422], @@ -503,25 +499,17 @@ class Arvados::V1::GroupsControllerTest < ActionController::TestCase end end - test 'get contents with jobs and pipeline instances disabled' do - Rails.configuration.API.DisabledAPIs = ConfigLoader.to_OrderedOptions( - {'jobs.index'=>{}, 'pipeline_instances.index'=>{}}) - - authorize_with :active - get :contents, params: { - id: groups(:aproject).uuid, - format: :json, - } - check_project_contents_response %w'arvados#pipelineInstance arvados#job' - end - test 'get contents with low max_index_database_read' do # Some result will certainly have at least 12 bytes in a - # restricted column + # restricted column. + # + # We cannot use collections.manifest_text to test this, because + # GroupsController refuses to select manifest_text, because + # controller doesn't sign manifests in a groups#contents response. Rails.configuration.API.MaxIndexDatabaseRead = 12 authorize_with :active get :contents, params: { - id: groups(:aproject).uuid, + uuid: users(:active).uuid, format: :json, } assert_response :success diff --git a/services/api/test/functional/arvados/v1/humans_controller_test.rb b/services/api/test/functional/arvados/v1/humans_controller_test.rb deleted file mode 100644 index d73fb30513..0000000000 --- a/services/api/test/functional/arvados/v1/humans_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::HumansControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/job_reuse_controller_test.rb b/services/api/test/functional/arvados/v1/job_reuse_controller_test.rb deleted file mode 100644 index 46cfac5c9a..0000000000 --- a/services/api/test/functional/arvados/v1/job_reuse_controller_test.rb +++ /dev/null @@ -1,106 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' -require 'helpers/git_test_helper' - -class Arvados::V1::JobReuseControllerTest < ActionController::TestCase - fixtures :repositories, :users, :jobs, :links, :collections - - setup do - @controller = Arvados::V1::JobsController.new - authorize_with :active - end - - BASE_FILTERS = { - 'repository' => ['=', 'active/foo'], - 'script' => ['=', 'hash'], - 'script_version' => ['in git', 'main'], - 'docker_image_locator' => ['=', nil], - 'arvados_sdk_version' => ['=', nil], - } - - def filters_from_hash(hash) - hash.each_pair.map { |name, filter| [name] + filter } - end - - test "find Job with script version range" do - get :index, params: { - filters: [["repository", "=", "active/foo"], - ["script", "=", "hash"], - ["script_version", "in git", "tag1"]] - } - assert_response :success - assert_not_nil assigns(:objects) - assert_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - end - - test "find Job with script version range exclusions" do - get :index, params: { - filters: [["repository", "=", "active/foo"], - ["script", "=", "hash"], - ["script_version", "not in git", "tag1"]] - } - assert_response :success - assert_not_nil assigns(:objects) - refute_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - end - - test "find Job with Docker image range" do - get :index, params: { - filters: [["docker_image_locator", "in docker", - "arvados/apitestfixture"]] - } - assert_response :success - assert_not_nil assigns(:objects) - assert_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_docker_job_run).uuid) - refute_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - end - - test "find Job with Docker image using reader tokens" do - authorize_with :inactive - get(:index, params: { - filters: [["docker_image_locator", "in docker", - "arvados/apitestfixture"]], - reader_tokens: [api_token(:active)], - }) - assert_response :success - assert_not_nil assigns(:objects) - assert_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_docker_job_run).uuid) - refute_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - end - - test "'in docker' filter accepts arrays" do - get :index, params: { - filters: [["docker_image_locator", "in docker", - ["_nonesuchname_", "arvados/apitestfixture"]]] - } - assert_response :success - assert_not_nil assigns(:objects) - assert_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_docker_job_run).uuid) - refute_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - end - - test "'not in docker' filter accepts arrays" do - get :index, params: { - filters: [["docker_image_locator", "not in docker", - ["_nonesuchname_", "arvados/apitestfixture"]]] - } - assert_response :success - assert_not_nil assigns(:objects) - assert_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_job_run).uuid) - refute_includes(assigns(:objects).map { |job| job.uuid }, - jobs(:previous_docker_job_run).uuid) - end - -end diff --git a/services/api/test/functional/arvados/v1/job_tasks_controller_test.rb b/services/api/test/functional/arvados/v1/job_tasks_controller_test.rb deleted file mode 100644 index d6f4347b87..0000000000 --- a/services/api/test/functional/arvados/v1/job_tasks_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::JobTasksControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/jobs_controller_test.rb b/services/api/test/functional/arvados/v1/jobs_controller_test.rb deleted file mode 100644 index 9298f23d54..0000000000 --- a/services/api/test/functional/arvados/v1/jobs_controller_test.rb +++ /dev/null @@ -1,191 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' -require 'helpers/git_test_helper' - -class Arvados::V1::JobsControllerTest < ActionController::TestCase - - test "search jobs by uuid with >= query" do - authorize_with :active - get :index, params: { - filters: [['uuid', '>=', 'zzzzz-8i9sb-pshmckwoma9plh7']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - assert_equal false, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j') - end - - test "search jobs by uuid with <= query" do - authorize_with :active - get :index, params: { - filters: [['uuid', '<=', 'zzzzz-8i9sb-pshmckwoma9plh7']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - assert_equal true, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j') - end - - test "search jobs by uuid with >= and <= query" do - authorize_with :active - get :index, params: { - filters: [['uuid', '>=', 'zzzzz-8i9sb-pshmckwoma9plh7'], - ['uuid', '<=', 'zzzzz-8i9sb-pshmckwoma9plh7']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal found, ['zzzzz-8i9sb-pshmckwoma9plh7'] - end - - test "search jobs by uuid with < query" do - authorize_with :active - get :index, params: { - filters: [['uuid', '<', 'zzzzz-8i9sb-pshmckwoma9plh7']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal false, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - assert_equal true, !!found.index('zzzzz-8i9sb-4cf0nhn6xte809j') - end - - test "search jobs by uuid with like query" do - authorize_with :active - get :index, params: { - filters: [['uuid', 'like', '%hmckwoma9pl%']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal found, ['zzzzz-8i9sb-pshmckwoma9plh7'] - end - - test "search jobs by uuid with 'in' query" do - authorize_with :active - get :index, params: { - filters: [['uuid', 'in', ['zzzzz-8i9sb-4cf0nhn6xte809j', - 'zzzzz-8i9sb-pshmckwoma9plh7']]] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal found.sort, ['zzzzz-8i9sb-4cf0nhn6xte809j', - 'zzzzz-8i9sb-pshmckwoma9plh7'] - end - - test "search jobs by uuid with 'not in' query" do - exclude_uuids = [jobs(:running).uuid, - jobs(:running_cancelled).uuid] - authorize_with :active - get :index, params: { - filters: [['uuid', 'not in', exclude_uuids]] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_not_empty found, "'not in' query returned nothing" - assert_empty(found & exclude_uuids, - "'not in' query returned uuids I asked not to get") - end - - ['=', '!='].each do |operator| - [['uuid', 'zzzzz-8i9sb-pshmckwoma9plh7'], - ['output', nil]].each do |attr, operand| - test "search jobs with #{attr} #{operator} #{operand.inspect} query" do - authorize_with :active - get :index, params: { - filters: [[attr, operator, operand]] - } - assert_response :success - values = assigns(:objects).collect { |x| x.send(attr) } - assert_not_empty values, "query should return non-empty result" - if operator == '=' - assert_empty values - [operand], "query results do not satisfy query" - else - assert_empty values & [operand], "query results do not satisfy query" - end - end - end - end - - test "search jobs by started_at with < query" do - authorize_with :active - get :index, params: { - filters: [['started_at', '<', Time.now.to_s]] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - end - - test "search jobs by started_at with > query" do - authorize_with :active - get :index, params: { - filters: [['started_at', '>', Time.now.to_s]] - } - assert_response :success - assert_equal 0, assigns(:objects).count - end - - test "search jobs by started_at with >= query on metric date" do - authorize_with :active - get :index, params: { - filters: [['started_at', '>=', '2014-01-01']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - end - - test "search jobs by started_at with >= query on metric date and time" do - authorize_with :active - get :index, params: { - filters: [['started_at', '>=', '2014-01-01 01:23:45']] - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-8i9sb-pshmckwoma9plh7') - end - - test "search jobs with 'any' operator" do - authorize_with :active - get :index, params: { - where: { any: ['contains', 'pshmckw'] } - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal 0, found.index('zzzzz-8i9sb-pshmckwoma9plh7') - assert_equal 1, found.count - end - - test "search jobs by nonexistent column with < query" do - authorize_with :active - get :index, params: { - filters: [['is_borked', '<', 'fizzbuzz']] - } - assert_response 422 - end - - [:spectator, :admin].each_with_index do |which_token, i| - test "get job queue as #{which_token} user" do - authorize_with which_token - get :queue - assert_response :success - assert_equal 0, assigns(:objects).count - end - end - - test "job includes assigned nodes" do - authorize_with :active - get :show, params: {id: jobs(:nearly_finished_job).uuid} - assert_response :success - assert_equal([nodes(:busy).uuid], json_response["node_uuids"]) - end - - test 'get job with components' do - authorize_with :active - get :show, params: {id: jobs(:running_job_with_components).uuid} - assert_response :success - assert_not_nil json_response["components"] - assert_equal ["component1", "component2"], json_response["components"].keys - end -end diff --git a/services/api/test/functional/arvados/v1/keep_disks_controller_test.rb b/services/api/test/functional/arvados/v1/keep_disks_controller_test.rb deleted file mode 100644 index 9da9d01631..0000000000 --- a/services/api/test/functional/arvados/v1/keep_disks_controller_test.rb +++ /dev/null @@ -1,102 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::KeepDisksControllerTest < ActionController::TestCase - - def default_ping_opts - {ping_secret: '', service_ssl_flag: false, service_port: 1234} - end - - test "add keep disk with admin token" do - authorize_with :admin - post :ping, params: default_ping_opts. - merge(filesystem_uuid: 'eb1e77a1-db84-4193-b6e6-ca2894f67d5f') - assert_response :success - assert_not_nil assigns(:object) - new_keep_disk = JSON.parse(@response.body) - assert_not_nil new_keep_disk['uuid'] - assert_not_nil new_keep_disk['ping_secret'] - assert_not_equal '', new_keep_disk['ping_secret'] - end - - [ - {}, - {filesystem_uuid: ''}, - ].each do |opts| - test "add keep disk with[out] filesystem_uuid #{opts}" do - authorize_with :admin - post :ping, params: default_ping_opts.merge(opts) - assert_response :success - assert_not_nil JSON.parse(@response.body)['uuid'] - end - end - - test "refuse to add keep disk without admin token" do - post :ping, params: default_ping_opts - assert_response 404 - end - - test "ping keep disk" do - post :ping, params: default_ping_opts. - merge(id: keep_disks(:nonfull).uuid, - ping_secret: keep_disks(:nonfull).ping_secret, - filesystem_uuid: keep_disks(:nonfull).filesystem_uuid) - assert_response :success - assert_not_nil assigns(:object) - keep_disk = JSON.parse(@response.body) - assert_not_nil keep_disk['uuid'] - assert_not_nil keep_disk['ping_secret'] - end - - test "admin should get index with ping_secret" do - authorize_with :admin - get :index - assert_response :success - assert_not_nil assigns(:objects) - items = JSON.parse(@response.body)['items'] - assert_not_equal 0, items.size - assert_not_nil items[0]['ping_secret'] - end - - # inactive user sees keep disks - test "inactive user should get index" do - authorize_with :inactive - get :index - assert_response :success - items = JSON.parse(@response.body)['items'] - assert_not_equal 0, items.size - - # Check these are still included - assert items[0]['service_host'] - assert items[0]['service_port'] - end - - # active user sees non-secret attributes of keep disks - test "active user should get non-empty index with no ping_secret" do - authorize_with :active - get :index - assert_response :success - items = JSON.parse(@response.body)['items'] - assert_not_equal 0, items.size - items.each do |item| - assert_nil item['ping_secret'] - assert_not_nil item['is_readable'] - assert_not_nil item['is_writable'] - assert_not_nil item['service_host'] - assert_not_nil item['service_port'] - end - end - - test "search keep_services with 'any' operator" do - authorize_with :active - get :index, params: { - where: { any: ['contains', 'o2t1q5w'] } - } - assert_response :success - found = assigns(:objects).collect(&:uuid) - assert_equal true, !!found.index('zzzzz-penuu-5w2o2t1q5wy7fhn') - end -end diff --git a/services/api/test/functional/arvados/v1/nodes_controller_test.rb b/services/api/test/functional/arvados/v1/nodes_controller_test.rb deleted file mode 100644 index 47f6c5ff3f..0000000000 --- a/services/api/test/functional/arvados/v1/nodes_controller_test.rb +++ /dev/null @@ -1,260 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::NodesControllerTest < ActionController::TestCase - - test "should get index with ping_secret" do - authorize_with :admin - get :index - assert_response :success - assert_not_nil assigns(:objects) - node_items = JSON.parse(@response.body)['items'] - assert_not_equal 0, node_items.size - assert_not_nil node_items[0]['info'].andand['ping_secret'] - end - - # inactive user does not see any nodes - test "inactive user should get empty index" do - authorize_with :inactive - get :index - assert_response :success - assert_equal 0, json_response['items'].size - assert_equal 0, json_response['items_available'] - end - - # active user sees non-secret attributes of up and recently-up nodes - test "active user should get non-empty index with no ping_secret" do - authorize_with :active - get :index - assert_response :success - assert_operator 0, :<, json_response['items_available'] - node_items = json_response['items'] - assert_operator 0, :<, node_items.size - found_busy_node = false - node_items.each do |node| - assert_nil node['info'].andand['ping_secret'] - assert_not_nil node['crunch_worker_state'] - if node['uuid'] == nodes(:busy).uuid - found_busy_node = true - assert_equal 'busy', node['crunch_worker_state'] - end - end - assert_equal true, found_busy_node - end - - test "node should ping with ping_secret and no token" do - post :ping, params: { - id: 'zzzzz-7ekkf-2z3mc76g2q73aio', - instance_id: 'i-0000000', - local_ipv4: '172.17.2.174', - ping_secret: '69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0' - } - assert_response :success - response = JSON.parse(@response.body) - assert_equal 'zzzzz-7ekkf-2z3mc76g2q73aio', response['uuid'] - # Ensure we are getting the "superuser" attributes, too - assert_not_nil response['first_ping_at'], '"first_ping_at" attr missing' - assert_not_nil response['info'], '"info" attr missing' - assert_not_nil response['nameservers'], '"nameservers" attr missing' - end - - test "node should fail ping with invalid ping_secret" do - post :ping, params: { - id: 'zzzzz-7ekkf-2z3mc76g2q73aio', - instance_id: 'i-0000000', - local_ipv4: '172.17.2.174', - ping_secret: 'dricrha4lcpi23pd69e44soanc069udawxvn3zzj45hs8bumvn' - } - assert_response 401 - end - - test "create node" do - authorize_with :admin - post :create, params: {node: {}} - assert_response :success - assert_not_nil json_response['uuid'] - assert_not_nil json_response['info'].is_a? Hash - assert_not_nil json_response['info']['ping_secret'] - assert_nil json_response['slot_number'] - assert_nil json_response['hostname'] - end - - test "create node and assign slot" do - authorize_with :admin - post :create, params: {node: {}, assign_slot: true} - assert_response :success - assert_not_nil json_response['uuid'] - assert_not_nil json_response['info'].is_a? Hash - assert_not_nil json_response['info']['ping_secret'] - assert_operator 0, :<, json_response['slot_number'] - n = json_response['slot_number'] - assert_equal "compute#{n}", json_response['hostname'] - - node = Node.where(uuid: json_response['uuid']).first - assert_equal n, node.slot_number - assert_equal "compute#{n}", node.hostname - end - - test "update node and assign slot" do - authorize_with :admin - node = nodes(:new_with_no_hostname) - post :update, params: {id: node.uuid, node: {}, assign_slot: true} - assert_response :success - assert_operator 0, :<, json_response['slot_number'] - n = json_response['slot_number'] - assert_equal "compute#{n}", json_response['hostname'] - - node.reload - assert_equal n, node.slot_number - assert_equal "compute#{n}", node.hostname - end - - test "update node and assign slot, don't clobber hostname" do - authorize_with :admin - node = nodes(:new_with_custom_hostname) - post :update, params: {id: node.uuid, node: {}, assign_slot: true} - assert_response :success - assert_operator 0, :<, json_response['slot_number'] - n = json_response['slot_number'] - assert_equal "custom1", json_response['hostname'] - end - - test "ping adds node stats to info" do - authorize_with :admin - node = nodes(:idle) - post :ping, params: { - id: node.uuid, - ping_secret: node.info['ping_secret'], - total_cpu_cores: 32, - total_ram_mb: 1024, - total_scratch_mb: 2048 - } - assert_response :success - info = JSON.parse(@response.body)['info'] - properties = JSON.parse(@response.body)['properties'] - assert_equal(node.info['ping_secret'], info['ping_secret']) - assert_equal(32, properties['total_cpu_cores'].to_i) - assert_equal(1024, properties['total_ram_mb'].to_i) - assert_equal(2048, properties['total_scratch_mb'].to_i) - end - - test "active user can see their assigned job" do - authorize_with :active - get :show, params: {id: nodes(:busy).uuid} - assert_response :success - assert_equal(jobs(:nearly_finished_job).uuid, json_response["job_uuid"]) - end - - test "user without job read permission can't see job" do - authorize_with :spectator - get :show, params: {id: nodes(:busy).uuid} - assert_response :success - assert_nil(json_response["job"], "spectator can see node's assigned job") - end - - [:admin, :spectator].each do |user| - test "select param does not break node list for #{user}" do - authorize_with user - get :index, params: {select: ['domain']} - assert_response :success - assert_operator 0, :<, json_response['items_available'] - end - end - - test "admin can associate a job with a node" do - changed_node = nodes(:idle) - assigned_job = jobs(:queued) - authorize_with :admin - post :update, params: { - id: changed_node.uuid, - node: {job_uuid: assigned_job.uuid}, - } - assert_response :success - assert_equal(changed_node.hostname, json_response["hostname"], - "hostname mismatch after defining job") - assert_equal(assigned_job.uuid, json_response["job_uuid"], - "mismatch in node's assigned job UUID") - end - - test "non-admin can't associate a job with a node" do - authorize_with :active - post :update, params: { - id: nodes(:idle).uuid, - node: {job_uuid: jobs(:queued).uuid}, - } - assert_response 403 - end - - test "admin can unassign a job from a node" do - changed_node = nodes(:busy) - authorize_with :admin - post :update, params: { - id: changed_node.uuid, - node: {job_uuid: nil}, - } - assert_response :success - assert_equal(changed_node.hostname, json_response["hostname"], - "hostname mismatch after defining job") - assert_nil(json_response["job_uuid"], - "node still has job assignment after update") - end - - test "non-admin can't unassign a job from a node" do - authorize_with :project_viewer - post :update, params: { - id: nodes(:busy).uuid, - node: {job_uuid: nil}, - } - assert_response 403 - end - - test "node should fail ping with invalid hostname config format" do - Rails.configuration.Containers.SLURM.Managed.AssignNodeHostname = 'compute%04' # should end with "04d" - post :ping, params: { - id: nodes(:new_with_no_hostname).uuid, - ping_secret: nodes(:new_with_no_hostname).info['ping_secret'], - } - assert_response 422 - end - - test "first ping should set ip addr using local_ipv4 when provided" do - post :ping, params: { - id: 'zzzzz-7ekkf-nodenoipaddryet', - instance_id: 'i-0000000', - local_ipv4: '172.17.2.172', - ping_secret: 'abcdyefg4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2' - } - assert_response :success - response = JSON.parse(@response.body) - assert_equal 'zzzzz-7ekkf-nodenoipaddryet', response['uuid'] - assert_equal '172.17.2.172', response['ip_address'] - end - - test "first ping should set ip addr using remote_ip when local_ipv4 is not provided" do - post :ping, params: { - id: 'zzzzz-7ekkf-nodenoipaddryet', - instance_id: 'i-0000000', - ping_secret: 'abcdyefg4lb5q4gzqqtrnq30oyj08r8dtdimmanbqw49z1anz2' - } - assert_response :success - response = JSON.parse(@response.body) - assert_equal 'zzzzz-7ekkf-nodenoipaddryet', response['uuid'] - assert_equal request.remote_ip, response['ip_address'] - end - - test "future pings should not change previous ip address" do - post :ping, params: { - id: 'zzzzz-7ekkf-2z3mc76g2q73aio', - instance_id: 'i-0000000', - local_ipv4: '172.17.2.175', - ping_secret: '69udawxvn3zzj45hs8bumvndricrha4lcpi23pd69e44soanc0' - } - assert_response :success - response = JSON.parse(@response.body) - assert_equal 'zzzzz-7ekkf-2z3mc76g2q73aio', response['uuid'] - assert_equal '172.17.2.174', response['ip_address'] # original ip address is not overwritten - end -end diff --git a/services/api/test/functional/arvados/v1/pipeline_instances_controller_test.rb b/services/api/test/functional/arvados/v1/pipeline_instances_controller_test.rb deleted file mode 100644 index e455354c11..0000000000 --- a/services/api/test/functional/arvados/v1/pipeline_instances_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::PipelineInstancesControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/pipeline_templates_controller_test.rb b/services/api/test/functional/arvados/v1/pipeline_templates_controller_test.rb deleted file mode 100644 index 992749c6f1..0000000000 --- a/services/api/test/functional/arvados/v1/pipeline_templates_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::PipelineTemplatesControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/repositories_controller_test.rb b/services/api/test/functional/arvados/v1/repositories_controller_test.rb deleted file mode 100644 index 84bd846c91..0000000000 --- a/services/api/test/functional/arvados/v1/repositories_controller_test.rb +++ /dev/null @@ -1,246 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::RepositoriesControllerTest < ActionController::TestCase - test "should get_all_logins with admin token" do - authorize_with :admin - get :get_all_permissions - assert_response :success - end - - test "should get_all_logins with non-admin token" do - authorize_with :active - get :get_all_permissions - assert_response 403 - end - - test "get_all_permissions gives RW to repository owner" do - authorize_with :admin - get :get_all_permissions - assert_response :success - ok = false - json_response['repositories'].each do |repo| - if repo['uuid'] == repositories(:repository2).uuid - if repo['user_permissions'][users(:active).uuid]['can_write'] - ok = true - end - end - end - assert_equal(true, ok, - "No permission on own repo '@{repositories(:repository2).uuid}'") - end - - test "get_all_permissions takes into account is_admin flag" do - authorize_with :admin - get :get_all_permissions - assert_response :success - json_response['repositories'].each do |repo| - assert_not_nil(repo['user_permissions'][users(:admin).uuid], - "Admin user is not listed in perms for #{repo['uuid']}") - assert_equal(true, - repo['user_permissions'][users(:admin).uuid]['can_write'], - "Admin has no perms for #{repo['uuid']}") - end - end - - test "get_all_permissions takes into account is_active flag" do - act_as_user users(:active) do - Repository.create! name: 'active/testrepo' - end - act_as_system_user do - u = users(:active) - u.unsetup - u.save! - end - authorize_with :admin - get :get_all_permissions - assert_response :success - json_response['repositories'].each do |r| - r['user_permissions'].each do |user_uuid, perms| - refute_equal user_uuid, users(:active).uuid - end - end - end - - test "get_all_permissions does not give any access to user without permission" do - viewer_uuid = users(:project_viewer).uuid - assert_equal(authorized_keys(:project_viewer).authorized_user_uuid, - viewer_uuid, - "project_viewer must have an authorized_key for this test to work") - authorize_with :admin - get :get_all_permissions - assert_response :success - readable_repos = json_response["repositories"].select do |repo| - repo["user_permissions"].has_key?(viewer_uuid) - end - assert_equal(["arvados"], readable_repos.map { |r| r["name"] }, - "project_viewer should only have permissions on public repos") - end - - test "get_all_permissions gives gitolite R to user with read-only access" do - authorize_with :admin - get :get_all_permissions - assert_response :success - found_it = false - assert_equal(authorized_keys(:spectator).authorized_user_uuid, - users(:spectator).uuid, - "spectator must have an authorized_key for this test to work") - json_response['repositories'].each do |repo| - next unless repo['uuid'] == repositories(:foo).uuid - assert_equal('R', - repo['user_permissions'][users(:spectator).uuid]['gitolite_permissions'], - "spectator user should have just R access to #{repo['uuid']}") - found_it = true - end - assert_equal true, found_it, "spectator user does not have R on foo repo" - end - - test "get_all_permissions provides admin and active user keys" do - authorize_with :admin - get :get_all_permissions - assert_response :success - [:active, :admin].each do |u| - assert_equal(1, json_response['user_keys'][users(u).uuid].andand.count, - "expected 1 key for #{u} (#{users(u).uuid})") - assert_equal(json_response['user_keys'][users(u).uuid][0]['public_key'], - authorized_keys(u).public_key, - "response public_key does not match fixture #{u}.") - end - end - - test "get_all_permissions lists all repos regardless of permissions" do - act_as_system_user do - # Create repos that could potentially be left out of the - # permission list by accident. - - # No authorized_key, no username (this can't even be done - # without skipping validations) - r = Repository.create name: 'root/testrepo' - assert r.save validate: false - - r = Repository.create name: 'invalid username / repo name', owner_uuid: users(:inactive).uuid - assert r.save validate: false - end - authorize_with :admin - get :get_all_permissions - assert_response :success - assert_equal(Repository.count, json_response["repositories"].size) - end - - test "get_all_permissions lists user permissions for users with no authorized keys" do - authorize_with :admin - AuthorizedKey.destroy_all - get :get_all_permissions - assert_response :success - assert_equal(Repository.count, json_response["repositories"].size) - repos_with_perms = [] - json_response['repositories'].each do |repo| - if repo['user_permissions'].any? - repos_with_perms << repo['uuid'] - end - end - assert_not_empty repos_with_perms, 'permissions are missing' - end - - # Ensure get_all_permissions correctly describes what the normal - # permission system would do. - test "get_all_permissions obeys group permissions" do - act_as_user system_user do - r = Repository.create!(name: 'admin/groupcanwrite', owner_uuid: users(:admin).uuid) - g = Group.create!(group_class: 'role', name: 'repo-writers') - u1 = users(:active) - u2 = users(:spectator) - Link.create!(tail_uuid: g.uuid, head_uuid: r.uuid, link_class: 'permission', name: 'can_manage') - Link.create!(tail_uuid: u1.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_write') - Link.create!(tail_uuid: u2.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_read') - - r = Repository.create!(name: 'admin/groupreadonly', owner_uuid: users(:admin).uuid) - g = Group.create!(group_class: 'role', name: 'repo-readers') - u1 = users(:active) - u2 = users(:spectator) - Link.create!(tail_uuid: g.uuid, head_uuid: r.uuid, link_class: 'permission', name: 'can_read') - Link.create!(tail_uuid: u1.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_write') - Link.create!(tail_uuid: u2.uuid, head_uuid: g.uuid, link_class: 'permission', name: 'can_read') - end - authorize_with :admin - get :get_all_permissions - assert_response :success - json_response['repositories'].each do |repo| - repo['user_permissions'].each do |user_uuid, perms| - u = User.find_by_uuid(user_uuid) - if perms['can_read'] - assert u.can? read: repo['uuid'] - assert_match(/R/, perms['gitolite_permissions']) - else - refute_match(/R/, perms['gitolite_permissions']) - end - if perms['can_write'] - assert u.can? write: repo['uuid'] - assert_match(/RW\+/, perms['gitolite_permissions']) - else - refute_match(/W/, perms['gitolite_permissions']) - end - if perms['can_manage'] - assert u.can? manage: repo['uuid'] - assert_match(/RW\+/, perms['gitolite_permissions']) - end - end - end - end - - test "default index includes fetch_url" do - authorize_with :active - get(:index) - assert_response :success - assert_includes(json_response["items"].map { |r| r["fetch_url"] }, - "git@git.zzzzz.arvadosapi.com:active/foo.git") - end - - [ - {cfg: "GitSSH.ExternalURL", cfgval: URI("ssh://git@example.com"), match: %r"^git@example.com:"}, - {cfg: "GitSSH.ExternalURL", cfgval: URI(""), match: %r"^git@git.zzzzz.arvadosapi.com:"}, - {cfg: "GitSSH", cfgval: false, refute: /^git@/ }, - {cfg: "GitHTTP.ExternalURL", cfgval: URI("https://example.com/"), match: %r"^https://example.com/"}, - {cfg: "GitHTTP.ExternalURL", cfgval: URI(""), match: %r"^https://git.zzzzz.arvadosapi.com/"}, - {cfg: "GitHTTP", cfgval: false, refute: /^http/ }, - ].each do |expect| - test "set #{expect[:cfg]} to #{expect[:cfgval]}" do - ConfigLoader.set_cfg Rails.configuration.Services, expect[:cfg].to_s, expect[:cfgval] - authorize_with :active - get :index - assert_response :success - assert_not_empty json_response['items'] - json_response['items'].each do |r| - if expect[:refute] - r['clone_urls'].each do |u| - refute_match expect[:refute], u - end - else - assert((r['clone_urls'].any? do |u| - expect[:match].match u - end), - "no match for #{expect[:match]} in #{r['clone_urls'].inspect}") - end - end - end - end - - test "select push_url in index" do - authorize_with :active - get(:index, params: {select: ["uuid", "push_url"]}) - assert_response :success - assert_includes(json_response["items"].map { |r| r["push_url"] }, - "git@git.zzzzz.arvadosapi.com:active/foo.git") - end - - test "select clone_urls in index" do - authorize_with :active - get(:index, params: {select: ["uuid", "clone_urls"]}) - assert_response :success - assert_includes(json_response["items"].map { |r| r["clone_urls"] }.flatten, - "git@git.zzzzz.arvadosapi.com:active/foo.git") - end -end diff --git a/services/api/test/functional/arvados/v1/schema_controller_test.rb b/services/api/test/functional/arvados/v1/schema_controller_test.rb index 65a2b64b8a..39b0cfe8f9 100644 --- a/services/api/test/functional/arvados/v1/schema_controller_test.rb +++ b/services/api/test/functional/arvados/v1/schema_controller_test.rb @@ -60,16 +60,16 @@ class Arvados::V1::SchemaControllerTest < ActionController::TestCase assert_response :success discovery_doc = JSON.parse(@response.body) assert_equal('POST', - discovery_doc['resources']['jobs']['methods']['create']['httpMethod']) + discovery_doc['resources']['collections']['methods']['create']['httpMethod']) end test "non-empty disable_api_methods" do Rails.configuration.API.DisabledAPIs = ConfigLoader.to_OrderedOptions( - {'jobs.create'=>{}, 'pipeline_instances.create'=>{}, 'pipeline_templates.create'=>{}}) + {'collections.create'=>{}, 'workflows.create'=>{}}) get :index assert_response :success discovery_doc = JSON.parse(@response.body) - ['jobs', 'pipeline_instances', 'pipeline_templates'].each do |r| + ['collections', 'workflows'].each do |r| refute_includes(discovery_doc['resources'][r]['methods'].keys(), 'create') end end @@ -97,10 +97,10 @@ class Arvados::V1::SchemaControllerTest < ActionController::TestCase discovery_doc = JSON.parse(@response.body) - specimens_index_params = discovery_doc['resources']['specimens']['methods']['index']['parameters'] # no changes from super + workflows_index_params = discovery_doc['resources']['workflows']['methods']['index']['parameters'] # no changes from super coll_index_params = discovery_doc['resources']['collections']['methods']['index']['parameters'] - assert_equal (specimens_index_params.keys + ['include_trash', 'include_old_versions']).sort, coll_index_params.keys.sort + assert_equal (workflows_index_params.keys + ['include_trash', 'include_old_versions']).sort, coll_index_params.keys.sort include_trash_param = coll_index_params['include_trash'] assert_equal 'boolean', include_trash_param['type'] diff --git a/services/api/test/functional/arvados/v1/specimens_controller_test.rb b/services/api/test/functional/arvados/v1/specimens_controller_test.rb deleted file mode 100644 index df681e6f5e..0000000000 --- a/services/api/test/functional/arvados/v1/specimens_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::SpecimensControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/traits_controller_test.rb b/services/api/test/functional/arvados/v1/traits_controller_test.rb deleted file mode 100644 index 3c8d097350..0000000000 --- a/services/api/test/functional/arvados/v1/traits_controller_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class Arvados::V1::TraitsControllerTest < ActionController::TestCase -end diff --git a/services/api/test/functional/arvados/v1/users_controller_test.rb b/services/api/test/functional/arvados/v1/users_controller_test.rb index cc0b5e1320..2b643d4b27 100644 --- a/services/api/test/functional/arvados/v1/users_controller_test.rb +++ b/services/api/test/functional/arvados/v1/users_controller_test.rb @@ -121,12 +121,10 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_nil updated['username'], 'expected no username' end - test "create user with user, vm and repo as input" do + test "create user with user and vm as input" do authorize_with :admin - repo_name = 'usertestrepo' post :setup, params: { - repo_name: repo_name, user: { uuid: 'zzzzz-tpzed-abcdefghijklmno', first_name: "in_create_test_first_name", @@ -145,11 +143,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # repo link and link add user to 'All users' group - verify_links_added 3 - - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - "foo/#{repo_name}", created['uuid'], 'arvados#repository', true, 'Repository' + # added links: vm permission, 'all users' group + verify_links_added 2 verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' @@ -165,7 +160,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase post :setup, params: { uuid: 'bogus_uuid', - repo_name: 'usertestrepo', vm_uuid: @vm_uuid } response_body = JSON.parse(@response.body) @@ -179,7 +173,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase post :setup, params: { user: {uuid: 'bogus_uuid'}, - repo_name: 'usertestrepo', vm_uuid: @vm_uuid, } response_body = JSON.parse(@response.body) @@ -193,7 +186,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase authorize_with :admin post :setup, params: { - repo_name: 'usertestrepo', vm_uuid: @vm_uuid, } response_body = JSON.parse(@response.body) @@ -208,7 +200,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase post :setup, params: { user: {}, - repo_name: 'usertestrepo', vm_uuid: @vm_uuid, } response_body = JSON.parse(@response.body) @@ -218,13 +209,12 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase 'Expected ArgumentError' end - test "invoke setup with existing uuid, vm and repo and verify links" do + test "invoke setup with existing uuid and vm permission, and verify links" do authorize_with :admin inactive_user = users(:inactive) post :setup, params: { uuid: users(:inactive).uuid, - repo_name: 'usertestrepo', vm_uuid: @vm_uuid } @@ -238,10 +228,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_equal inactive_user['email'], resp_obj['email'], 'expecting inactive user email' - # expect repo and vm links - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'inactiveuser/usertestrepo', resp_obj['uuid'], 'arvados#repository', true, 'Repository' - + # expect vm permission link verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', @vm_uuid, resp_obj['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' end @@ -266,7 +253,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase 'expecting inactive user email' end - test "setup user with valid email and repo as input" do + test "setup user with valid email and repo(ignored) as input" do authorize_with :admin post :setup, params: { @@ -280,15 +267,14 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil response_object['uuid'], 'expected uuid for the new user' assert_equal response_object['email'], 'foo@example.com', 'expected given email' - # three extra links; system_group, group and repo perms - verify_links_added 3 + # added links: system_group, 'all users' group. + verify_links_added 2 end test "setup user with fake vm and expect error" do authorize_with :admin post :setup, params: { - repo_name: 'usertestrepo', vm_uuid: 'no_such_vm', user: {email: 'foo@example.com'}, } @@ -300,11 +286,10 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase 'Expected RuntimeError: No vm found for no_such_vm' end - test "setup user with valid email, repo and real vm as input" do + test "setup user with valid email and real vm as input" do authorize_with :admin post :setup, params: { - repo_name: 'usertestrepo', vm_uuid: @vm_uuid, user: {email: 'foo@example.com'} } @@ -315,8 +300,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil response_object['uuid'], 'expected uuid for the new user' assert_equal response_object['email'], 'foo@example.com', 'expected given email' - # four extra links; system_group, group, vm, repo - verify_links_added 4 + # added links; system_group, 'all users' group, vm. + verify_links_added 3 end test "setup user with valid email, no vm and no repo as input" do @@ -332,24 +317,20 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil response_object['uuid'], 'expected uuid for new user' assert_equal response_object['email'], 'foo@example.com', 'expected given email' - # two extra links; system_group, and group + # added links; system_group, 'all users' group. verify_links_added 2 verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', response_object['uuid'], 'arvados#group', true, 'Group' - verify_link response_items, 'arvados#repository', false, 'permission', 'can_manage', - 'foo/usertestrepo', response_object['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', nil, response_object['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' end - test "setup user with email, first name, repo name and vm uuid" do + test "setup user with email, first name, and vm uuid" do authorize_with :admin post :setup, params: { - repo_name: 'usertestrepo', vm_uuid: @vm_uuid, user: { first_name: 'test_first_name', @@ -365,8 +346,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_equal 'test_first_name', response_object['first_name'], 'expecting first name' - # four extra links; system_group, group, repo and vm - verify_links_added 4 + # added links: system_group, 'all users' group, vm. + verify_links_added 3 end test "setup user with an existing user email and check different object is created" do @@ -374,7 +355,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase inactive_user = users(:inactive) post :setup, params: { - repo_name: 'usertestrepo', user: { email: inactive_user['email'] } @@ -387,15 +367,14 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_equal response_object['uuid'], inactive_user['uuid'], 'expected different uuid after create operation' assert_equal inactive_user['email'], response_object['email'], 'expected given email' - # system_group, group, and repo. No vm link. - verify_links_added 3 + # added links: system_group, 'all users' group. + verify_links_added 2 end test "setup user with openid prefix" do authorize_with :admin post :setup, params: { - repo_name: 'usertestrepo', user: { first_name: "in_create_test_first_name", last_name: "test_last_name", @@ -413,12 +392,8 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # verify links - # three new links: system_group, repo, and 'All users' group. - verify_links_added 3 - - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' + # added links: system_group, 'all users' group. + verify_links_added 2 verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' @@ -427,7 +402,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' end - test "setup user with user, vm and repo and verify links" do + test "setup user with user and vm, and verify links" do authorize_with :admin post :setup, params: { @@ -437,7 +412,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase email: "foo@example.com" }, vm_uuid: @vm_uuid, - repo_name: 'usertestrepo', } assert_response :success @@ -450,14 +424,11 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # four new links: system_group, repo, vm and 'All users' group link - verify_links_added 4 + # added links: system_group, 'all users' group, vm + verify_links_added 3 # system_group isn't part of the response. See User#add_system_group_permission_link - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' @@ -493,13 +464,11 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase 'Expected Forbidden error' end - test "setup active user with repo and no vm" do + test "setup active user with no vm" do authorize_with :admin active_user = users(:active) - # invoke setup with a repository post :setup, params: { - repo_name: 'usertestrepo', uuid: active_user['uuid'] } @@ -510,13 +479,10 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase assert_equal active_user[:email], created['email'], 'expected input email' - # verify links + # verify links verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'active/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' end @@ -524,13 +490,7 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase test "setup active user with vm and no repo" do authorize_with :admin active_user = users(:active) - repos_query = Repository.where(owner_uuid: active_user.uuid) - repo_link_query = Link.where(tail_uuid: active_user.uuid, - link_class: "permission", name: "can_manage") - repos_count = repos_query.count - repo_link_count = repo_link_query.count - # invoke setup with a repository post :setup, params: { vm_uuid: @vm_uuid, uuid: active_user['uuid'], @@ -548,9 +508,6 @@ class Arvados::V1::UsersControllerTest < ActionController::TestCase verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' - assert_equal(repos_count, repos_query.count) - assert_equal(repo_link_count, repo_link_query.count) - verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', @vm_uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' end @@ -655,7 +612,6 @@ The Arvados team. authorize_with :admin active_user = users(:active) - # invoke setup with a repository put :update, params: { id: active_user['uuid'], user: { diff --git a/services/api/test/functional/database_controller_test.rb b/services/api/test/functional/database_controller_test.rb index ef1d0c6d05..ea44cbf453 100644 --- a/services/api/test/functional/database_controller_test.rb +++ b/services/api/test/functional/database_controller_test.rb @@ -40,12 +40,12 @@ class DatabaseControllerTest < ActionController::TestCase test "reset succeeds with admin token" do new_uuid = nil act_as_system_user do - new_uuid = Specimen.create.uuid + new_uuid = Collection.create.uuid end - assert_not_empty Specimen.where(uuid: new_uuid) + assert_not_empty Collection.where(uuid: new_uuid) authorize_with :admin post :reset assert_response 200 - assert_empty Specimen.where(uuid: new_uuid) + assert_empty Collection.where(uuid: new_uuid) end end diff --git a/services/api/test/functional/sys_controller_test.rb b/services/api/test/functional/sys_controller_test.rb index e13d702983..ab304c1c7c 100644 --- a/services/api/test/functional/sys_controller_test.rb +++ b/services/api/test/functional/sys_controller_test.rb @@ -96,7 +96,6 @@ class SysControllerTest < ActionController::TestCase g_bar = groups(:trashed_subproject) g_baz = groups(:trashed_subproject3) col = collections(:collection_in_trashed_subproject) - job = jobs(:job_in_trashed_project) cr = container_requests(:cr_in_trashed_project) # Save how many objects were before the sweep user_nr_was = User.all.length @@ -104,12 +103,10 @@ class SysControllerTest < ActionController::TestCase group_nr_was = Group.where('group_class<>?', 'project').length project_nr_was = Group.where(group_class: 'project').length cr_nr_was = ContainerRequest.all.length - job_nr_was = Job.all.length assert_not_empty Group.where(uuid: g_foo.uuid) assert_not_empty Group.where(uuid: g_bar.uuid) assert_not_empty Group.where(uuid: g_baz.uuid) assert_not_empty Collection.where(uuid: col.uuid) - assert_not_empty Job.where(uuid: job.uuid) assert_not_empty ContainerRequest.where(uuid: cr.uuid) authorize_with :admin @@ -120,7 +117,6 @@ class SysControllerTest < ActionController::TestCase assert_empty Group.where(uuid: g_bar.uuid) assert_empty Group.where(uuid: g_baz.uuid) assert_empty Collection.where(uuid: col.uuid) - assert_empty Job.where(uuid: job.uuid) assert_empty ContainerRequest.where(uuid: cr.uuid) # No unwanted deletions should have happened assert_equal user_nr_was, User.all.length @@ -129,7 +125,6 @@ class SysControllerTest < ActionController::TestCase assert_equal group_nr_was, Group.where('group_class<>?', 'project').length assert_equal project_nr_was-3, Group.where(group_class: 'project').length assert_equal cr_nr_was-1, ContainerRequest.all.length - assert_equal job_nr_was-1, Job.all.length end end diff --git a/services/api/test/helpers/git_test_helper.rb b/services/api/test/helpers/git_test_helper.rb deleted file mode 100644 index cb30f68015..0000000000 --- a/services/api/test/helpers/git_test_helper.rb +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'fileutils' -require 'tmpdir' - -# Commit log for "foo" repository in test.git.tar -# main is the main branch -# b1 is a branch off of main -# tag1 is a tag -# -# 1de84a8 * b1 -# 077ba2a * main -# 4fe459a * tag1 -# 31ce37f * foo - -module GitTestHelper - def self.included base - base.setup do - # Extract the test repository data into the default test - # environment's Rails.configuration.Git.Repositories. (We - # don't use that config setting here, though: it doesn't seem - # worth the risk of stepping on a real git repo root.) - @tmpdir = Rails.root.join 'tmp', 'git' - FileUtils.mkdir_p @tmpdir - system("tar", "-xC", @tmpdir.to_s, "-f", "test/test.git.tar") - Rails.configuration.Git.Repositories = "#{@tmpdir}/test" - Rails.configuration.Containers.JobsAPI.GitInternalDir = "#{@tmpdir}/internal.git" - end - - base.teardown do - FileUtils.remove_entry CommitsHelper.cache_dir_base, true - FileUtils.mkdir_p @tmpdir - system("tar", "-xC", @tmpdir.to_s, "-f", "test/test.git.tar") - end - end - - def internal_tag tag - IO.read "|git --git-dir #{Rails.configuration.Containers.JobsAPI.GitInternalDir.shellescape} log --format=format:%H -n1 #{tag.shellescape}" - end - - # Intercept fetch_remote_repository and fetch from a specified url - # or local fixture instead of the remote url requested. fakeurl can - # be a url (probably starting with file:///) or the name of a - # fixture (as a symbol) - def fetch_remote_from_local_repo url, fakeurl - if fakeurl.is_a? Symbol - fakeurl = 'file://' + repositories(fakeurl).server_path - end - CommitsHelper.expects(:fetch_remote_repository).once.with do |gitdir, giturl| - if giturl == url - CommitsHelper.unstub(:fetch_remote_repository) - CommitsHelper.fetch_remote_repository gitdir, fakeurl - true - end - end - end -end diff --git a/services/api/test/helpers/users_test_helper.rb b/services/api/test/helpers/users_test_helper.rb index e106d994cd..c4dc72d3ba 100644 --- a/services/api/test/helpers/users_test_helper.rb +++ b/services/api/test/helpers/users_test_helper.rb @@ -54,14 +54,10 @@ module UsersTestHelper # these don't get added any more! they shouldn't appear ever. assert !oid_login_perms.any?, "expected all oid_login_perms deleted" + # these don't get added any more! they shouldn't appear ever. repo_perms = Link.where(tail_uuid: uuid, - link_class: 'permission', - name: 'can_manage').where("head_uuid like ?", Repository.uuid_like_pattern) - if expect_repo_perms - assert repo_perms.any?, "expected repo_perms" - else - assert !repo_perms.any?, "expected all repo_perms deleted" - end + link_class: 'permission').where("head_uuid like ?", '_____-s0uqq-_______________') + assert !repo_perms.any?, "expected all repo_perms deleted" vm_login_perms = Link. where(tail_uuid: uuid, diff --git a/services/api/test/integration/api_client_authorizations_scopes_test.rb b/services/api/test/integration/api_client_authorizations_scopes_test.rb index 3b28a3163f..83a6337644 100644 --- a/services/api/test/integration/api_client_authorizations_scopes_test.rb +++ b/services/api/test/integration/api_client_authorizations_scopes_test.rb @@ -44,15 +44,15 @@ class ApiTokensScopeTest < ActionDispatch::IntegrationTest assert_response 403 end - test "specimens token can see exactly owned specimens" do - get_args = {params: {}, headers: auth(:active_specimens)} - get(v1_url('specimens'), **get_args) + test "collections token can see exactly owned collections" do + get_args = {params: {}, headers: auth(:active_all_collections)} + get(v1_url('collections'), **get_args) assert_response 403 - get(v1_url('specimens', specimens(:owned_by_active_user).uuid), **get_args) + get(v1_url('collections', collections(:collection_owned_by_active).uuid), **get_args) assert_response :success - head(v1_url('specimens', specimens(:owned_by_active_user).uuid), **get_args) + head(v1_url('collections', collections(:collection_owned_by_active).uuid), **get_args) assert_response :success - get(v1_url('specimens', specimens(:owned_by_spectator).uuid), **get_args) + get(v1_url('collections', collections(:collection_owned_by_foo).uuid), **get_args) assert_includes(403..404, @response.status) end diff --git a/services/api/test/integration/bundler_version_test.rb b/services/api/test/integration/bundler_version_test.rb new file mode 100644 index 0000000000..fb1634cf90 --- /dev/null +++ b/services/api/test/integration/bundler_version_test.rb @@ -0,0 +1,19 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +require 'test_helper' + +class BundlerVersionTest < ActionDispatch::IntegrationTest + test "Bundler version matches expectations" do + # The expected version range should be the latest that supports all the + # versions of Ruby we intend to support. This test checks that a developer + # doesn't accidentally update Bundler past that point. + expected = Gem::Dependency.new("", "~> 2.4.22") + actual = Bundler.gem_version + assert( + expected.match?("", actual), + "Bundler version #{actual} did not match #{expected}", + ) + end +end diff --git a/services/api/test/integration/database_reset_test.rb b/services/api/test/integration/database_reset_test.rb index 7015453a9a..aa778dbf9f 100644 --- a/services/api/test/integration/database_reset_test.rb +++ b/services/api/test/integration/database_reset_test.rb @@ -31,22 +31,22 @@ class DatabaseResetTest < ActionDispatch::IntegrationTest post '/database/reset', params: {}, headers: admin_auth assert_response :success - post '/arvados/v1/specimens', params: {specimen: '{}'}, headers: active_auth + post '/arvados/v1/collections', params: {collection: '{}'}, headers: active_auth assert_response :success new_uuid = json_response['uuid'] - get '/arvados/v1/specimens/'+new_uuid, params: {}, headers: active_auth + get '/arvados/v1/collections/'+new_uuid, params: {}, headers: active_auth assert_response :success - put('/arvados/v1/specimens/'+new_uuid, - params: {specimen: '{"properties":{}}'}, + put('/arvados/v1/collections/'+new_uuid, + params: {collection: '{"properties":{}}'}, headers: active_auth) assert_response :success - delete '/arvados/v1/specimens/'+new_uuid, params: {}, headers: active_auth + delete '/arvados/v1/collections/'+new_uuid, params: {}, headers: active_auth assert_response :success - get '/arvados/v1/specimens/'+new_uuid, params: {}, headers: active_auth + get '/arvados/v1/collections/'+new_uuid, params: {}, headers: active_auth assert_response 404 end @@ -54,14 +54,14 @@ class DatabaseResetTest < ActionDispatch::IntegrationTest active_auth = auth(:active) admin_auth = auth(:admin) - old_uuid = specimens(:owned_by_active_user).uuid + old_uuid = collections(:collection_owned_by_active).uuid authorize_with :admin post '/database/reset', params: {}, headers: admin_auth assert_response :success - delete '/arvados/v1/specimens/' + old_uuid, params: {}, headers: active_auth + delete '/arvados/v1/collections/' + old_uuid, params: {}, headers: active_auth assert_response :success - post '/arvados/v1/specimens', params: {specimen: '{}'}, headers: active_auth + post '/arvados/v1/collections', params: {collection: '{}'}, headers: active_auth assert_response :success new_uuid = json_response['uuid'] @@ -69,10 +69,10 @@ class DatabaseResetTest < ActionDispatch::IntegrationTest post '/database/reset', params: {}, headers: admin_auth assert_response :success - # New specimen should disappear. Old specimen should reappear. - get '/arvados/v1/specimens/'+new_uuid, params: {}, headers: active_auth + # New collection should disappear. Old collection should reappear. + get '/arvados/v1/collections/'+new_uuid, params: {}, headers: active_auth assert_response 404 - get '/arvados/v1/specimens/'+old_uuid, params: {}, headers: active_auth + get '/arvados/v1/collections/'+old_uuid, params: {}, headers: active_auth assert_response :success end end diff --git a/services/api/test/integration/groups_test.rb b/services/api/test/integration/groups_test.rb index e76f2b5406..bc5a08c2c8 100644 --- a/services/api/test/integration/groups_test.rb +++ b/services/api/test/integration/groups_test.rb @@ -140,7 +140,7 @@ class GroupsTest < ActionDispatch::IntegrationTest test 'count none works with offset' do first_results = nil - (0..10).each do |offset| + (0..5).each do |offset| get "/arvados/v1/groups/contents", params: { id: groups(:aproject).uuid, offset: offset, diff --git a/services/api/test/integration/jobs_api_test.rb b/services/api/test/integration/jobs_api_test.rb deleted file mode 100644 index 76d4fff59e..0000000000 --- a/services/api/test/integration/jobs_api_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class JobsApiTest < ActionDispatch::IntegrationTest -end diff --git a/services/api/test/integration/login_workflow_test.rb b/services/api/test/integration/login_workflow_test.rb index ba3b2ac6e3..7ad95ceebf 100644 --- a/services/api/test/integration/login_workflow_test.rb +++ b/services/api/test/integration/login_workflow_test.rb @@ -6,8 +6,8 @@ require 'test_helper' class LoginWorkflowTest < ActionDispatch::IntegrationTest test "default prompt to login is JSON" do - post('/arvados/v1/specimens', - params: {specimen: {}}, + post('/arvados/v1/collections', + params: {collection: {}}, headers: {'HTTP_ACCEPT' => ''}) assert_response 401 json_response['errors'].each do |err| @@ -16,8 +16,8 @@ class LoginWorkflowTest < ActionDispatch::IntegrationTest end test "login prompt respects JSON Accept header" do - post('/arvados/v1/specimens', - params: {specimen: {}}, + post('/arvados/v1/collections', + params: {collection: {}}, headers: {'HTTP_ACCEPT' => 'application/json'}) assert_response 401 json_response['errors'].each do |err| @@ -26,8 +26,8 @@ class LoginWorkflowTest < ActionDispatch::IntegrationTest end test "login prompt respects HTML Accept header" do - post('/arvados/v1/specimens', - params: {specimen: {}}, + post('/arvados/v1/collections', + params: {collection: {}}, headers: {'HTTP_ACCEPT' => 'text/html'}) assert_response 302 assert_match(%r{http://www.example.com/login$}, @response.headers['Location'], diff --git a/services/api/test/integration/permissions_test.rb b/services/api/test/integration/permissions_test.rb index d2dce44f01..9636a82011 100644 --- a/services/api/test/integration/permissions_test.rb +++ b/services/api/test/integration/permissions_test.rb @@ -302,26 +302,29 @@ class PermissionsTest < ActionDispatch::IntegrationTest assert_response 404 end - test "RO group-admin finds user's specimens, RW group-admin can update" do + test "RO group-admin finds user's collections, RW group-admin can update" do + other_user_collection = act_as_user(users(:user_foo_in_sharing_group)) do + Collection.create() + end [[:rominiadmin, false], [:miniadmin, true]].each do |which_user, update_should_succeed| - get "/arvados/v1/specimens", + get "/arvados/v1/collections", params: {:format => :json}, headers: auth(which_user) assert_response :success resp_uuids = json_response['items'].collect { |i| i['uuid'] } - [[true, specimens(:owned_by_active_user).uuid], - [true, specimens(:owned_by_private_group).uuid], - [false, specimens(:owned_by_spectator).uuid], + [[true, collections(:collection_owned_by_active).uuid], + [true, collections(:foo_collection_in_aproject).uuid], + [false, other_user_collection.uuid], ].each do |should_find, uuid| assert_equal(should_find, !resp_uuids.index(uuid).nil?, - "%s should%s see %s in specimen list" % + "%s should%s see %s in collection list" % [which_user.to_s, - should_find ? '' : 'not ', + should_find ? '' : ' not', uuid]) - put "/arvados/v1/specimens/#{uuid}", + put "/arvados/v1/collections/#{uuid}", params: { - :specimen => { + :collection => { properties: { miniadmin_was_here: true } diff --git a/services/api/test/integration/reader_tokens_test.rb b/services/api/test/integration/reader_tokens_test.rb index e8e8c910c7..891bffbb1d 100644 --- a/services/api/test/integration/reader_tokens_test.rb +++ b/services/api/test/integration/reader_tokens_test.rb @@ -7,20 +7,20 @@ require 'test_helper' class ReaderTokensTest < ActionDispatch::IntegrationTest fixtures :all - def spectator_specimen - specimens(:owned_by_spectator).uuid + def owned_by_foo + collections(:collection_owned_by_foo).uuid end - def get_specimens(main_auth, read_auth, formatter=:to_a) + def get_collections(main_auth, read_auth, formatter=:to_a) params = {} params[:reader_tokens] = [api_token(read_auth)].send(formatter) if read_auth headers = {} headers.merge!(auth(main_auth)) if main_auth - get('/arvados/v1/specimens', params: params, headers: headers) + get('/arvados/v1/collections', params: params, headers: headers) end - def get_specimen_uuids(main_auth, read_auth, formatter=:to_a) - get_specimens(main_auth, read_auth, formatter) + def get_collection_uuids(main_auth, read_auth, formatter=:to_a) + get_collections(main_auth, read_auth, formatter) assert_response :success json_response['items'].map { |spec| spec['uuid'] } end @@ -33,26 +33,26 @@ class ReaderTokensTest < ActionDispatch::IntegrationTest headers = {} expected = 401 end - post('/arvados/v1/specimens.json', - params: {specimen: {}, reader_tokens: [api_token(read_auth)].send(formatter)}, + post('/arvados/v1/collections.json', + params: {collection: {}, reader_tokens: [api_token(read_auth)].send(formatter)}, headers: headers) assert_response expected end - test "active user can't see spectator specimen" do + test "active user can't see foo-owned collection" do # Other tests in this suite assume that the active user doesn't - # have read permission to the owned_by_spectator specimen. + # have read permission to the owned_by_foo collection. # This test checks that this assumption still holds. - refute_includes(get_specimen_uuids(:active, nil), spectator_specimen, - ["active user can read the owned_by_spectator specimen", + refute_includes(get_collection_uuids(:active, nil), owned_by_foo, + ["active user can read the owned_by_foo collection", "other tests will return false positives"].join(" - ")) end [nil, :active_noscope].each do |main_auth| - [:spectator, :spectator_specimens].each do |read_auth| + [:foo, :foo_collections].each do |read_auth| [:to_a, :to_json].each do |formatter| test "#{main_auth.inspect} auth with #{formatter} reader token #{read_auth} can#{"'t" if main_auth} read" do - get_specimens(main_auth, read_auth) + get_collections(main_auth, read_auth) assert_response(if main_auth then 403 else 200 end) end @@ -65,18 +65,18 @@ class ReaderTokensTest < ActionDispatch::IntegrationTest test "scopes are still limited with reader tokens" do get('/arvados/v1/collections', - params: {reader_tokens: [api_token(:spectator_specimens)]}, + params: {reader_tokens: [api_token(:foo_collections)]}, headers: auth(:active_noscope)) assert_response 403 end test "reader tokens grant no permissions when expired" do - get_specimens(:active_noscope, :expired) + get_collections(:active_noscope, :expired) assert_response 403 end test "reader tokens grant no permissions outside their scope" do - refute_includes(get_specimen_uuids(:active, :admin_vm), spectator_specimen, + refute_includes(get_collection_uuids(:active, :admin_vm), owned_by_foo, "scoped reader token granted permissions out of scope") end end diff --git a/services/api/test/integration/serialized_encoding_test.rb b/services/api/test/integration/serialized_encoding_test.rb index f41c033b39..bf2d0062f2 100644 --- a/services/api/test/integration/serialized_encoding_test.rb +++ b/services/api/test/integration/serialized_encoding_test.rb @@ -3,26 +3,13 @@ # SPDX-License-Identifier: AGPL-3.0 require 'test_helper' -require 'helpers/git_test_helper' class SerializedEncodingTest < ActionDispatch::IntegrationTest - include GitTestHelper - fixtures :all { api_client_authorization: {scopes: []}, - - human: {properties: {eye_color: 'gray'}}, - link: {link_class: 'test', name: 'test', properties: {foo: :bar}}, - - node: {info: {uptime: 1234}}, - - specimen: {properties: {eye_color: 'meringue'}}, - - trait: {properties: {eye_color: 'brown'}}, - user: {prefs: {cookies: 'thin mint'}}, }.each_pair do |resource, postdata| test "create json-encoded #{resource.to_s}" do diff --git a/services/api/test/integration/user_sessions_test.rb b/services/api/test/integration/user_sessions_test.rb index eb49cf832e..2b37454218 100644 --- a/services/api/test/integration/user_sessions_test.rb +++ b/services/api/test/integration/user_sessions_test.rb @@ -87,22 +87,20 @@ class UserSessionsApiTest < ActionDispatch::IntegrationTest # Test various combinations of auto_setup configuration and email # address provided during a new user's first session setup. - [{result: :nope, email: nil, cfg: {auto: true, repo: true, vm: true}}, + [{result: :nope, email: nil, cfg: {auto: true, vm: true}}, {result: :yup, email: nil, cfg: {auto: true}}, - {result: :nope, email: '@example.com', cfg: {auto: true, repo: true, vm: true}}, + {result: :nope, email: '@example.com', cfg: {auto: true, vm: true}}, {result: :yup, email: '@example.com', cfg: {auto: true}}, - {result: :nope, email: 'root@', cfg: {auto: true, repo: true, vm: true}}, - {result: :nope, email: 'root@', cfg: {auto: true, repo: true}}, {result: :nope, email: 'root@', cfg: {auto: true, vm: true}}, - {result: :yup, email: 'root@', cfg: {auto: true}}, - {result: :nope, email: 'gitolite@', cfg: {auto: true, repo: true}}, + {result: :nope, email: 'root@', cfg: {auto: true}}, + {result: :nope, email: 'gitolite@', cfg: {auto: true}}, {result: :nope, email: '*_*@', cfg: {auto: true, vm: true}}, {result: :yup, email: 'toor@', cfg: {auto: true, vm: true, repo: true}}, {result: :yup, email: 'foo@', cfg: {auto: true, vm: true}, uniqprefix: 'foo'}, - {result: :yup, email: 'foo@', cfg: {auto: true, repo: true}, + {result: :yup, email: 'foo@', cfg: {auto: true}, uniqprefix: 'foo'}, - {result: :yup, email: 'auto_setup_vm_login@', cfg: {auto: true, repo: true}, + {result: :yup, email: 'auto_setup_vm_login@', cfg: {auto: true}, uniqprefix: 'auto_setup_vm_login'}, ].each do |testcase| test "user auto-activate #{testcase.inspect}" do @@ -111,23 +109,16 @@ class UserSessionsApiTest < ActionDispatch::IntegrationTest Rails.configuration.Users.AutoSetupNewUsers = testcase[:cfg][:auto] Rails.configuration.Users.AutoSetupNewUsersWithVmUUID = (testcase[:cfg][:vm] ? virtual_machines(:testvm).uuid : "") - Rails.configuration.Users.AutoSetupNewUsersWithRepository = - testcase[:cfg][:repo] mock_auth_with(email: testcase[:email]) u = assigns(:user) vm_links = Link.where('link_class=? and tail_uuid=? and head_uuid like ?', 'permission', u.uuid, '%-' + VirtualMachine.uuid_prefix + '-%') - repo_links = Link.where('link_class=? and tail_uuid=? and head_uuid like ?', - 'permission', u.uuid, - '%-' + Repository.uuid_prefix + '-%') - repos = Repository.where('uuid in (?)', repo_links.collect(&:head_uuid)) case u[:result] when :nope assert_equal false, u.is_invited, "should not have been set up" assert_empty vm_links, "should not have VM login permission" - assert_empty repo_links, "should not have repo permission" when :yup assert_equal true, u.is_invited if testcase[:cfg][:vm] @@ -135,21 +126,11 @@ class UserSessionsApiTest < ActionDispatch::IntegrationTest else assert_empty vm_links, "should not have VM login permission" end - if testcase[:cfg][:repo] - assert_equal 1, repo_links.count, "wrong number of repo perm links" - assert_equal 1, repos.count, "wrong number of repos" - assert_equal 'can_manage', repo_links.first.name, "wrong perm type" - else - assert_empty repo_links, "should not have repo permission" - end end if (prefix = testcase[:uniqprefix]) # This email address conflicts with a test fixture. Make sure - # every VM login and repository name got digits added to make - # it unique. - (repos.collect(&:name) + - vm_links.collect { |link| link.properties['username'] } - ).each do |name| + # every VM login got digits added to make it unique. + vm_links.collect { |link| link.properties['username'] }.each do |name| r = name.match(/^(.{#{prefix.length}})(\d+)$/) assert_not_nil r, "#{name.inspect} does not match {prefix}\\d+" assert_equal(prefix, r[1], diff --git a/services/api/test/integration/users_test.rb b/services/api/test/integration/users_test.rb index f8956b21e2..a7d6245443 100644 --- a/services/api/test/integration/users_test.rb +++ b/services/api/test/integration/users_test.rb @@ -9,11 +9,8 @@ class UsersTest < ActionDispatch::IntegrationTest include UsersTestHelper test "setup user multiple times" do - repo_name = 'usertestrepo' - post "/arvados/v1/users/setup", params: { - repo_name: repo_name, user: { uuid: 'zzzzz-tpzed-abcdefghijklmno', first_name: "in_create_test_first_name", @@ -35,10 +32,7 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # repo link and link add user to 'All users' group - - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' + # link to add user to 'All users' group verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' @@ -51,7 +45,6 @@ class UsersTest < ActionDispatch::IntegrationTest # invoke setup again with the same data post "/arvados/v1/users/setup", params: { - repo_name: repo_name, vm_uuid: virtual_machines(:testvm).uuid, user: { uuid: 'zzzzz-tpzed-abcdefghijklmno', @@ -66,7 +59,6 @@ class UsersTest < ActionDispatch::IntegrationTest # invoke setup on the same user post "/arvados/v1/users/setup", params: { - repo_name: repo_name, vm_uuid: virtual_machines(:testvm).uuid, uuid: 'zzzzz-tpzed-abcdefghijklmno', }, @@ -81,10 +73,7 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['email'], 'expected non-nil email' assert_nil created['identity_url'], 'expected no identity_url' - # arvados#user, repo link and link add user to 'All users' group - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/usertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - + # arvados#user, and link to add user to 'All users' group verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' @@ -119,31 +108,6 @@ class UsersTest < ActionDispatch::IntegrationTest verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' - # invoke setup with a repository - post "/arvados/v1/users/setup", - params: { - repo_name: 'newusertestrepo', - uuid: created['uuid'] - }, - headers: auth(:admin) - - assert_response :success - - response_items = json_response['items'] - created = find_obj_in_resp response_items, 'arvados#user', nil - - assert_equal 'foo@example.com', created['email'], 'expected input email' - - # verify links - verify_link response_items, 'arvados#group', true, 'permission', 'can_write', - 'All users', created['uuid'], 'arvados#group', true, 'Group' - - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/newusertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - - verify_link response_items, 'arvados#virtualMachine', false, 'permission', 'can_login', - nil, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' - # invoke setup with a vm_uuid post "/arvados/v1/users/setup", params: { @@ -173,7 +137,6 @@ class UsersTest < ActionDispatch::IntegrationTest test "setup and unsetup user" do post "/arvados/v1/users/setup", params: { - repo_name: 'newusertestrepo', vm_uuid: virtual_machines(:testvm).uuid, user: {email: 'foo@example.com'}, }, @@ -185,14 +148,11 @@ class UsersTest < ActionDispatch::IntegrationTest assert_not_nil created['uuid'], 'expected uuid for the new user' assert_equal created['email'], 'foo@example.com', 'expected given email' - # four extra links: system_group, login, group, repo and vm + # three extra links: system_group, login, group and vm verify_link response_items, 'arvados#group', true, 'permission', 'can_write', 'All users', created['uuid'], 'arvados#group', true, 'Group' - verify_link response_items, 'arvados#repository', true, 'permission', 'can_manage', - 'foo/newusertestrepo', created['uuid'], 'arvados#repository', true, 'Repository' - verify_link response_items, 'arvados#virtualMachine', true, 'permission', 'can_login', virtual_machines(:testvm).uuid, created['uuid'], 'arvados#virtualMachine', false, 'VirtualMachine' @@ -276,13 +236,6 @@ class UsersTest < ActionDispatch::IntegrationTest assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) assert_equal(users(:project_viewer).uuid, json_response['authorized_user_uuid']) - get('/arvados/v1/repositories/' + repositories(:foo).uuid, - params: {}, - headers: auth(:active)) - assert_response(:success) - assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) - assert_equal("#{users(:project_viewer).username}/foo", json_response['name']) - get('/arvados/v1/groups/' + groups(:aproject).uuid, params: {}, headers: auth(:active)) @@ -317,41 +270,6 @@ class UsersTest < ActionDispatch::IntegrationTest assert_equal 'barney', json_response['username'] end - test 'merge with repository name conflict' do - post('/arvados/v1/groups', - params: { - group: { - group_class: 'project', - name: "active user's stuff", - }, - }, - headers: auth(:project_viewer)) - assert_response(:success) - project_uuid = json_response['uuid'] - - post('/arvados/v1/repositories/', - params: { :repository => { :name => "#{users(:project_viewer).username}/foo", :owner_uuid => users(:project_viewer).uuid } }, - headers: auth(:project_viewer)) - assert_response(:success) - - post('/arvados/v1/users/merge', - params: { - new_user_token: api_client_authorizations(:project_viewer_trustedclient).api_token, - new_owner_uuid: project_uuid, - redirect_to_new_user: true, - }, - headers: auth(:active_trustedclient)) - assert_response(:success) - - get('/arvados/v1/repositories/' + repositories(:foo).uuid, - params: {}, - headers: auth(:active)) - assert_response(:success) - assert_equal(users(:project_viewer).uuid, json_response['owner_uuid']) - assert_equal("#{users(:project_viewer).username}/migratedfoo", json_response['name']) - - end - test "cannot set is_active to false directly" do post('/arvados/v1/users', params: { diff --git a/services/api/test/test.git.tar b/services/api/test/test.git.tar deleted file mode 100644 index 7af80b0774..0000000000 Binary files a/services/api/test/test.git.tar and /dev/null differ diff --git a/services/api/test/unit/arvados_model_test.rb b/services/api/test/unit/arvados_model_test.rb index 69a2710bb9..341a8462dd 100644 --- a/services/api/test/unit/arvados_model_test.rb +++ b/services/api/test/unit/arvados_model_test.rb @@ -8,20 +8,20 @@ class ArvadosModelTest < ActiveSupport::TestCase fixtures :all def create_with_attrs attrs - a = Specimen.create({material: 'caloric'}.merge(attrs)) + a = Collection.create({properties: {'foo' => 'bar'}}.merge(attrs)) a if a.valid? end test 'non-admin cannot assign uuid' do set_user_from_auth :active_trustedclient - want_uuid = Specimen.generate_uuid + want_uuid = Collection.generate_uuid a = create_with_attrs(uuid: want_uuid) assert_nil a, "Non-admin should not assign uuid." end test 'admin can assign valid uuid' do set_user_from_auth :admin_trustedclient - want_uuid = Specimen.generate_uuid + want_uuid = Collection.generate_uuid a = create_with_attrs(uuid: want_uuid) assert_equal want_uuid, a.uuid, "Admin should assign valid uuid." assert a.uuid.length==27, "Auto assigned uuid length is wrong." @@ -29,7 +29,7 @@ class ArvadosModelTest < ActiveSupport::TestCase test 'admin cannot assign uuid with wrong object type' do set_user_from_auth :admin_trustedclient - want_uuid = Human.generate_uuid + want_uuid = Group.generate_uuid a = create_with_attrs(uuid: want_uuid) assert_nil a, "Admin should not be able to assign invalid uuid." end @@ -126,10 +126,23 @@ class ArvadosModelTest < ActiveSupport::TestCase end test "search index exists on models that go into projects" do - all_tables = ActiveRecord::Base.connection.tables - all_tables.delete 'schema_migrations' - all_tables.delete 'permission_refresh_lock' - all_tables.delete 'ar_internal_metadata' + all_tables = ActiveRecord::Base.connection.tables - [ + 'ar_internal_metadata', + 'permission_refresh_lock', + 'schema_migrations', + # tables that may still exist in the database even though model + # classes have been deleted: + 'humans', + 'jobs', + 'job_tasks', + 'keep_disks', + 'nodes', + 'pipeline_instances', + 'pipeline_templates', + 'repositories', + 'specimens', + 'traits', + ] all_tables.each do |table| table_class = table.classify.constantize @@ -159,9 +172,6 @@ class ArvadosModelTest < ActiveSupport::TestCase %w[collections collections_trgm_text_search_idx], %w[container_requests container_requests_trgm_text_search_idx], %w[groups groups_trgm_text_search_idx], - %w[jobs jobs_trgm_text_search_idx], - %w[pipeline_instances pipeline_instances_trgm_text_search_idx], - %w[pipeline_templates pipeline_templates_trgm_text_search_idx], %w[workflows workflows_trgm_text_search_idx] ].each do |model| table = model[0] @@ -180,25 +190,25 @@ class ArvadosModelTest < ActiveSupport::TestCase end test "selectable_attributes includes database attributes" do - assert_includes(Job.selectable_attributes, "success") + assert_includes(Collection.selectable_attributes, "name") end test "selectable_attributes includes non-database attributes" do - assert_includes(Job.selectable_attributes, "node_uuids") + assert_includes(Collection.selectable_attributes, "unsigned_manifest_text") end test "selectable_attributes includes common attributes in extensions" do - assert_includes(Job.selectable_attributes, "uuid") + assert_includes(Collection.selectable_attributes, "uuid") end test "selectable_attributes does not include unexposed attributes" do - refute_includes(Job.selectable_attributes, "nodes") + refute_includes(Collection.selectable_attributes, "id") end test "selectable_attributes on a non-default template" do - attr_a = Job.selectable_attributes(:common) + attr_a = Collection.selectable_attributes(:common) assert_includes(attr_a, "uuid") - refute_includes(attr_a, "success") + refute_includes(attr_a, "name") end test 'create and retrieve using created_at time' do @@ -260,19 +270,21 @@ class ArvadosModelTest < ActiveSupport::TestCase else Rails.configuration.AuditLogs.MaxAge = 0 end + tested_serialized = false [ User.find_by_uuid(users(:active).uuid), ContainerRequest.find_by_uuid(container_requests(:queued).uuid), Container.find_by_uuid(containers(:queued).uuid), - PipelineInstance.find_by_uuid(pipeline_instances(:has_component_with_completed_jobs).uuid), - PipelineTemplate.find_by_uuid(pipeline_templates(:two_part).uuid), - Job.find_by_uuid(jobs(:running).uuid) + Group.find_by_uuid(groups(:afiltergroup).uuid), + Collection.find_by_uuid(collections(:collection_with_one_property).uuid), ].each do |obj| - assert_not(obj.class.serialized_attributes.empty?, - "#{obj.class} model doesn't have serialized attributes") + if !obj.class.serialized_attributes.empty? + tested_serialized = true + end # obj shouldn't have changed since it's just retrieved from the database assert_not(obj.changed?, "#{obj.class} model's attribute(s) appear as changed: '#{obj.changes.keys.join(',')}' with audit logs #{auditlogs_enabled ? '': 'not '}enabled.") end + assert(tested_serialized, "did not test any models with serialized attributes") end end end diff --git a/services/api/test/unit/commit_ancestor_test.rb b/services/api/test/unit/commit_ancestor_test.rb deleted file mode 100644 index 46041211bb..0000000000 --- a/services/api/test/unit/commit_ancestor_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class CommitAncestorTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/services/api/test/unit/commit_test.rb b/services/api/test/unit/commit_test.rb deleted file mode 100644 index e83061f61a..0000000000 --- a/services/api/test/unit/commit_test.rb +++ /dev/null @@ -1,270 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' -require 'helpers/git_test_helper' - -# NOTE: calling Commit.find_commit_range(nil, nil, 'rev') -# produces an error message "fatal: bad object 'rev'" on stderr if -# 'rev' does not exist in a given repository. Many of these tests -# report such errors; their presence does not represent a fatal -# condition. - -class CommitTest < ActiveSupport::TestCase - # See git_setup.rb for the commit log for test.git.tar - include GitTestHelper - - setup do - authorize_with :active - end - - test 'find_commit_range does not bypass permissions' do - authorize_with :inactive - assert_raises ArgumentError do - CommitsHelper::find_commit_range 'foo', nil, 'main', [] - end - end - - def must_pipe(cmd) - begin - return IO.read("|#{cmd}") - ensure - assert $?.success? - end - end - - [ - 'https://github.com/arvados/arvados.git', - 'http://github.com/arvados/arvados.git', - 'git://github.com/arvados/arvados.git', - ].each do |url| - test "find_commit_range uses fetch_remote_repository to get #{url}" do - fake_gitdir = repositories(:foo).server_path - CommitsHelper::expects(:cache_dir_for).once.with(url).returns fake_gitdir - CommitsHelper::expects(:fetch_remote_repository).once.with(fake_gitdir, url).returns true - c = CommitsHelper::find_commit_range url, nil, 'main', [] - refute_empty c - end - end - - [ - 'bogus/repo', - '/bogus/repo', - '/not/allowed/.git', - 'file:///not/allowed.git', - 'git.arvados.org/arvados.git', - 'github.com/arvados/arvados.git', - ].each do |url| - test "find_commit_range skips fetch_remote_repository for #{url}" do - CommitsHelper::expects(:fetch_remote_repository).never - assert_raises ArgumentError do - CommitsHelper::find_commit_range url, nil, 'main', [] - end - end - end - - test 'fetch_remote_repository does not leak commits across repositories' do - url = "http://localhost:1/fake/fake.git" - fetch_remote_from_local_repo url, :foo - c = CommitsHelper::find_commit_range url, nil, 'main', [] - assert_equal ['077ba2ad3ea24a929091a9e6ce545c93199b8e57'], c - - url = "http://localhost:2/fake/fake.git" - fetch_remote_from_local_repo url, 'file://' + File.expand_path('../../.git', Rails.root) - c = CommitsHelper::find_commit_range url, nil, '077ba2ad3ea24a929091a9e6ce545c93199b8e57', [] - assert_equal [], c - end - - test 'tag_in_internal_repository creates and updates tags in internal.git' do - authorize_with :active - gitint = "git --git-dir #{Rails.configuration.Containers.JobsAPI.GitInternalDir}" - IO.read("|#{gitint} tag -d testtag 2>/dev/null") # "no such tag", fine - assert_match(/^fatal: /, IO.read("|#{gitint} show testtag 2>&1")) - refute $?.success? - CommitsHelper::tag_in_internal_repository 'active/foo', '31ce37fe365b3dc204300a3e4c396ad333ed0556', 'testtag' - assert_match(/^commit 31ce37f/, IO.read("|#{gitint} show testtag")) - assert $?.success? - end - - def with_foo_repository - Dir.chdir("#{Rails.configuration.Git.Repositories}/#{repositories(:foo).uuid}") do - must_pipe("git checkout main 2>&1") - yield - end - end - - test 'tag_in_internal_repository, new non-tip sha1 in local repo' do - tag = "tag#{rand(10**10)}" - sha1 = nil - with_foo_repository do - must_pipe("git checkout -b branch-#{rand(10**10)} 2>&1") - must_pipe("echo -n #{tag.shellescape} >bar") - must_pipe("git add bar") - must_pipe("git -c user.email=x@x -c user.name=X commit -m -") - sha1 = must_pipe("git log -n1 --format=%H").strip - must_pipe("git rm bar") - must_pipe("git -c user.email=x@x -c user.name=X commit -m -") - end - CommitsHelper::tag_in_internal_repository 'active/foo', sha1, tag - gitint = "git --git-dir #{Rails.configuration.Containers.JobsAPI.GitInternalDir.shellescape}" - assert_match(/^commit /, IO.read("|#{gitint} show #{tag.shellescape}")) - assert $?.success? - end - - test 'tag_in_internal_repository, new unreferenced sha1 in local repo' do - tag = "tag#{rand(10**10)}" - sha1 = nil - with_foo_repository do - must_pipe("echo -n #{tag.shellescape} >bar") - must_pipe("git add bar") - must_pipe("git -c user.email=x@x -c user.name=X commit -m -") - sha1 = must_pipe("git log -n1 --format=%H").strip - must_pipe("git reset --hard HEAD^") - end - CommitsHelper::tag_in_internal_repository 'active/foo', sha1, tag - gitint = "git --git-dir #{Rails.configuration.Containers.JobsAPI.GitInternalDir.shellescape}" - assert_match(/^commit /, IO.read("|#{gitint} show #{tag.shellescape}")) - assert $?.success? - end - - # In active/shabranchnames, "7387838c69a21827834586cc42b467ff6c63293b" is - # both a commit hash, and the name of a branch that begins from that same - # commit. - COMMIT_BRANCH_NAME = "7387838c69a21827834586cc42b467ff6c63293b" - # A commit that appears in the branch after 7387838c. - COMMIT_BRANCH_COMMIT_2 = "abec49829bf1758413509b7ffcab32a771b71e81" - # "738783" is another branch that starts from the above commit. - SHORT_COMMIT_BRANCH_NAME = COMMIT_BRANCH_NAME[0, 6] - # A commit that appears in branch 738783 after 7387838c. - SHORT_BRANCH_COMMIT_2 = "77e1a93093663705a63bb4d505698047e109dedd" - - test "find_commit_range min_version prefers commits over branch names" do - assert_equal([COMMIT_BRANCH_NAME], - CommitsHelper::find_commit_range("active/shabranchnames", - COMMIT_BRANCH_NAME, nil, nil)) - end - - test "find_commit_range max_version prefers commits over branch names" do - assert_equal([COMMIT_BRANCH_NAME], - CommitsHelper::find_commit_range("active/shabranchnames", - nil, COMMIT_BRANCH_NAME, nil)) - end - - test "find_commit_range min_version with short branch name" do - assert_equal([SHORT_BRANCH_COMMIT_2], - CommitsHelper::find_commit_range("active/shabranchnames", - SHORT_COMMIT_BRANCH_NAME, nil, nil)) - end - - test "find_commit_range max_version with short branch name" do - assert_equal([SHORT_BRANCH_COMMIT_2], - CommitsHelper::find_commit_range("active/shabranchnames", - nil, SHORT_COMMIT_BRANCH_NAME, nil)) - end - - test "find_commit_range min_version with disambiguated branch name" do - assert_equal([COMMIT_BRANCH_COMMIT_2], - CommitsHelper::find_commit_range("active/shabranchnames", - "heads/#{COMMIT_BRANCH_NAME}", - nil, nil)) - end - - test "find_commit_range max_version with disambiguated branch name" do - assert_equal([COMMIT_BRANCH_COMMIT_2], - CommitsHelper::find_commit_range("active/shabranchnames", nil, - "heads/#{COMMIT_BRANCH_NAME}", nil)) - end - - test "find_commit_range min_version with unambiguous short name" do - assert_equal([COMMIT_BRANCH_NAME], - CommitsHelper::find_commit_range("active/shabranchnames", - COMMIT_BRANCH_NAME[0..-2], nil, nil)) - end - - test "find_commit_range max_version with unambiguous short name" do - assert_equal([COMMIT_BRANCH_NAME], - CommitsHelper::find_commit_range("active/shabranchnames", nil, - COMMIT_BRANCH_NAME[0..-2], nil)) - end - - test "find_commit_range laundry list" do - authorize_with :active - - # single - a = CommitsHelper::find_commit_range('active/foo', nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil) - assert_equal ['31ce37fe365b3dc204300a3e4c396ad333ed0556'], a - - #test "test_branch1" do - a = CommitsHelper::find_commit_range('active/foo', nil, 'main', nil) - assert_includes(a, '077ba2ad3ea24a929091a9e6ce545c93199b8e57') - - #test "test_branch2" do - a = CommitsHelper::find_commit_range('active/foo', nil, 'b1', nil) - assert_equal ['1de84a854e2b440dc53bf42f8548afa4c17da332'], a - - #test "test_branch3" do - a = CommitsHelper::find_commit_range('active/foo', nil, 'HEAD', nil) - assert_equal ['1de84a854e2b440dc53bf42f8548afa4c17da332'], a - - #test "test_single_revision_repo" do - a = CommitsHelper::find_commit_range('active/foo', nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil) - assert_equal ['31ce37fe365b3dc204300a3e4c396ad333ed0556'], a - a = CommitsHelper::find_commit_range('arvados', nil, '31ce37fe365b3dc204300a3e4c396ad333ed0556', nil) - assert_equal [], a - - #test "test_multi_revision" do - # complains "fatal: bad object 077ba2ad3ea24a929091a9e6ce545c93199b8e57" - a = CommitsHelper::find_commit_range('active/foo', '31ce37fe365b3dc204300a3e4c396ad333ed0556', '077ba2ad3ea24a929091a9e6ce545c93199b8e57', nil) - assert_equal ['077ba2ad3ea24a929091a9e6ce545c93199b8e57', '4fe459abe02d9b365932b8f5dc419439ab4e2577', '31ce37fe365b3dc204300a3e4c396ad333ed0556'], a - - #test "test_tag" do - # complains "fatal: ambiguous argument 'tag1': unknown revision or path - # not in the working tree." - a = CommitsHelper::find_commit_range('active/foo', 'tag1', 'main', nil) - assert_equal ['077ba2ad3ea24a929091a9e6ce545c93199b8e57', '4fe459abe02d9b365932b8f5dc419439ab4e2577'], a - - #test "test_multi_revision_exclude" do - a = CommitsHelper::find_commit_range('active/foo', '31ce37fe365b3dc204300a3e4c396ad333ed0556', '077ba2ad3ea24a929091a9e6ce545c93199b8e57', ['4fe459abe02d9b365932b8f5dc419439ab4e2577']) - assert_equal ['077ba2ad3ea24a929091a9e6ce545c93199b8e57', '31ce37fe365b3dc204300a3e4c396ad333ed0556'], a - - #test "test_multi_revision_tagged_exclude" do - # complains "fatal: bad object 077ba2ad3ea24a929091a9e6ce545c93199b8e57" - a = CommitsHelper::find_commit_range('active/foo', '31ce37fe365b3dc204300a3e4c396ad333ed0556', '077ba2ad3ea24a929091a9e6ce545c93199b8e57', ['tag1']) - assert_equal ['077ba2ad3ea24a929091a9e6ce545c93199b8e57', '31ce37fe365b3dc204300a3e4c396ad333ed0556'], a - - Dir.mktmpdir do |touchdir| - # invalid input to maximum - a = CommitsHelper::find_commit_range('active/foo', nil, "31ce37fe365b3dc204300a3e4c396ad333ed0556 ; touch #{touchdir}/uh_oh", nil) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'maximum' parameter of find_commit_range is exploitable" - assert_equal [], a - - # invalid input to maximum - a = CommitsHelper::find_commit_range('active/foo', nil, "$(uname>#{touchdir}/uh_oh)", nil) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'maximum' parameter of find_commit_range is exploitable" - assert_equal [], a - - # invalid input to minimum - a = CommitsHelper::find_commit_range('active/foo', "31ce37fe365b3dc204300a3e4c396ad333ed0556 ; touch #{touchdir}/uh_oh", "31ce37fe365b3dc204300a3e4c396ad333ed0556", nil) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'minimum' parameter of find_commit_range is exploitable" - assert_equal [], a - - # invalid input to minimum - a = CommitsHelper::find_commit_range('active/foo', "$(uname>#{touchdir}/uh_oh)", "31ce37fe365b3dc204300a3e4c396ad333ed0556", nil) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'minimum' parameter of find_commit_range is exploitable" - assert_equal [], a - - # invalid input to 'excludes' - # complains "fatal: bad object 077ba2ad3ea24a929091a9e6ce545c93199b8e57" - a = CommitsHelper::find_commit_range('active/foo', "31ce37fe365b3dc204300a3e4c396ad333ed0556", "077ba2ad3ea24a929091a9e6ce545c93199b8e57", ["4fe459abe02d9b365932b8f5dc419439ab4e2577 ; touch #{touchdir}/uh_oh"]) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'excludes' parameter of find_commit_range is exploitable" - assert_equal [], a - - # invalid input to 'excludes' - # complains "fatal: bad object 077ba2ad3ea24a929091a9e6ce545c93199b8e57" - a = CommitsHelper::find_commit_range('active/foo', "31ce37fe365b3dc204300a3e4c396ad333ed0556", "077ba2ad3ea24a929091a9e6ce545c93199b8e57", ["$(uname>#{touchdir}/uh_oh)"]) - assert !File.exist?("#{touchdir}/uh_oh"), "#{touchdir}/uh_oh should not exist, 'excludes' parameter of find_commit_range is exploitable" - assert_equal [], a - end - end -end diff --git a/services/api/test/unit/container_request_test.rb b/services/api/test/unit/container_request_test.rb index d25c08a579..fa7910d597 100644 --- a/services/api/test/unit/container_request_test.rb +++ b/services/api/test/unit/container_request_test.rb @@ -112,11 +112,15 @@ class ContainerRequestTest < ActiveSupport::TestCase {"mounts" => {"FOO" => {}}}, {"mounts" => {"FOO" => {"kind" => "tmp", "capacity" => 42.222}}}, {"command" => ["echo", 55]}, - {"environment" => {"FOO" => 55}} + {"environment" => {"FOO" => 55}}, + {"output_glob" => [false]}, + {"output_glob" => [["bad"]]}, + {"output_glob" => "bad"}, + {"output_glob" => ["nope", -1]}, ].each do |value| test "Create with invalid #{value}" do set_user_from_auth :active - assert_raises(ActiveRecord::RecordInvalid) do + assert_raises(ActiveRecord::RecordInvalid, Serializer::TypeMismatch) do cr = create_minimal_req!({state: "Committed", priority: 1}.merge(value)) cr.save! @@ -127,7 +131,7 @@ class ContainerRequestTest < ActiveSupport::TestCase set_user_from_auth :active cr = create_minimal_req!(state: "Uncommitted", priority: 1) cr.save! - assert_raises(ActiveRecord::RecordInvalid) do + assert_raises(ActiveRecord::RecordInvalid, Serializer::TypeMismatch) do cr = ContainerRequest.find_by_uuid cr.uuid cr.update!({state: "Committed", priority: 1}.merge(value)) diff --git a/services/api/test/unit/container_test.rb b/services/api/test/unit/container_test.rb index 09b885b391..88496b793f 100644 --- a/services/api/test/unit/container_test.rb +++ b/services/api/test/unit/container_test.rb @@ -22,6 +22,7 @@ class ContainerTest < ActiveSupport::TestCase cwd: "test", command: ["echo", "hello"], output_path: "test", + output_glob: [], runtime_constraints: { "API" => false, "keep_cache_disk" => 0, @@ -48,6 +49,7 @@ class ContainerTest < ActiveSupport::TestCase environment: {}, mounts: {}, output_path: "test", + output_glob: [], runtime_auth_scopes: ["all"], runtime_constraints: { "API" => false, @@ -333,7 +335,7 @@ class ContainerTest < ActiveSupport::TestCase set_user_from_auth :dispatch1 out1 = '1f4b0bc7583c2a7f9102c395f4ffc5e3+45' - log1 = collections(:real_log_collection).portable_data_hash + log1 = collections(:log_collection).portable_data_hash c_output1.update!({state: Container::Locked}) c_output1.update!({state: Container::Running}) c_output1.update!(completed_attrs.merge({log: log1, output: out1})) @@ -845,7 +847,7 @@ class ContainerTest < ActiveSupport::TestCase assert c.lock, show_errors(c) assert c.update( state: Container::Cancelled, - log: collections(:real_log_collection).portable_data_hash, + log: collections(:log_collection).portable_data_hash, ), show_errors(c) check_no_change_from_cancelled c end @@ -933,7 +935,7 @@ class ContainerTest < ActiveSupport::TestCase test "locked_by_uuid can update log when locked/running, and output when running" do set_user_from_auth :active - logcoll = collections(:real_log_collection) + logcoll = collections(:container_log_collection) c, cr1 = minimal_new cr2 = ContainerRequest.new(DEFAULT_ATTRS) cr2.state = ContainerRequest::Committed @@ -975,8 +977,8 @@ class ContainerTest < ActiveSupport::TestCase assert_equal cr1log_uuid, cr1.log_uuid assert_equal cr2log_uuid, cr2.log_uuid assert_equal 1, Collection.where(uuid: [cr1log_uuid, cr2log_uuid]).to_a.collect(&:portable_data_hash).uniq.length - assert_equal ". acbd18db4cc2f85cedef654fccc4a4d8+3 cdd549ae79fe6640fa3d5c6261d8303c+195 0:3:foo.txt 3:195:zzzzz-8i9sb-0vsrcqi7whchuil.log.txt -./log\\040for\\040container\\040#{cr1.container_uuid} acbd18db4cc2f85cedef654fccc4a4d8+3 cdd549ae79fe6640fa3d5c6261d8303c+195 0:3:foo.txt 3:195:zzzzz-8i9sb-0vsrcqi7whchuil.log.txt + assert_equal ". 8c12f5f5297b7337598170c6f531fcee+7882 acbd18db4cc2f85cedef654fccc4a4d8+3 0:0:arv-mount.txt 0:1910:container.json 1910:1264:crunch-run.txt 3174:1005:crunchstat.txt 7882:3:foo.txt 4179:659:hoststat.txt 4838:2811:node-info.txt 7649:233:node.json 0:0:stderr.txt +./log\\040for\\040container\\040#{cr1.container_uuid} 8c12f5f5297b7337598170c6f531fcee+7882 acbd18db4cc2f85cedef654fccc4a4d8+3 0:0:arv-mount.txt 0:1910:container.json 1910:1264:crunch-run.txt 3174:1005:crunchstat.txt 7882:3:foo.txt 4179:659:hoststat.txt 4838:2811:node-info.txt 7649:233:node.json 0:0:stderr.txt ", Collection.find_by_uuid(cr1log_uuid).manifest_text end @@ -1013,7 +1015,7 @@ class ContainerTest < ActiveSupport::TestCase assert c.update(runtime_status: {'warning' => 'something happened'}) assert c.update(progress: 0.5) assert c.update(exit_code: 0) - refute c.update(log: collections(:real_log_collection).portable_data_hash) + refute c.update(log: collections(:log_collection).portable_data_hash) c.reload assert c.update(state: Container::Complete, exit_code: 0) end diff --git a/services/api/test/unit/group_test.rb b/services/api/test/unit/group_test.rb index 36f42006ff..e03ca8da05 100644 --- a/services/api/test/unit/group_test.rb +++ b/services/api/test/unit/group_test.rb @@ -18,13 +18,13 @@ class GroupTest < ActiveSupport::TestCase assert g.save, "active user should be able to modify group #{g.uuid}" # Use the group as the owner of a new object - s = Specimen. + s = Collection. create(owner_uuid: groups(:bad_group_has_ownership_cycle_b).uuid) assert s.valid?, "ownership should pass validation #{s.errors.messages}" assert_equal false, s.save, "should not save object with #{g.uuid} as owner" # Use the group as the new owner of an existing object - s = specimens(:in_aproject) + s = collections(:collection_owned_by_active) s.owner_uuid = groups(:bad_group_has_ownership_cycle_b).uuid assert s.valid?, "ownership should pass validation" assert_equal false, s.save, "should not save object with #{g.uuid} as owner" diff --git a/services/api/test/unit/helpers/api_client_authorizations_helper_test.rb b/services/api/test/unit/helpers/api_client_authorizations_helper_test.rb deleted file mode 100644 index 01ed4302da..0000000000 --- a/services/api/test/unit/helpers/api_client_authorizations_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class ApiClientAuthorizationsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/api_clients_helper_test.rb b/services/api/test/unit/helpers/api_clients_helper_test.rb deleted file mode 100644 index 4901fb45df..0000000000 --- a/services/api/test/unit/helpers/api_clients_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class ApiClientsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/authorized_keys_helper_test.rb b/services/api/test/unit/helpers/authorized_keys_helper_test.rb deleted file mode 100644 index 010a0fe453..0000000000 --- a/services/api/test/unit/helpers/authorized_keys_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class AuthorizedKeysHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/collections_helper_test.rb b/services/api/test/unit/helpers/collections_helper_test.rb deleted file mode 100644 index dd01ca7b82..0000000000 --- a/services/api/test/unit/helpers/collections_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class CollectionsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/commit_ancestors_helper_test.rb b/services/api/test/unit/helpers/commit_ancestors_helper_test.rb deleted file mode 100644 index 423dbf6769..0000000000 --- a/services/api/test/unit/helpers/commit_ancestors_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class CommitAncestorsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/commits_helper_test.rb b/services/api/test/unit/helpers/commits_helper_test.rb deleted file mode 100644 index fd960a86f3..0000000000 --- a/services/api/test/unit/helpers/commits_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class CommitsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/groups_helper_test.rb b/services/api/test/unit/helpers/groups_helper_test.rb deleted file mode 100644 index ce7a3fad2b..0000000000 --- a/services/api/test/unit/helpers/groups_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class GroupsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/humans_helper_test.rb b/services/api/test/unit/helpers/humans_helper_test.rb deleted file mode 100644 index 22f9e819ce..0000000000 --- a/services/api/test/unit/helpers/humans_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class HumansHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/job_tasks_helper_test.rb b/services/api/test/unit/helpers/job_tasks_helper_test.rb deleted file mode 100644 index af0302ccf3..0000000000 --- a/services/api/test/unit/helpers/job_tasks_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class JobTasksHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/jobs_helper_test.rb b/services/api/test/unit/helpers/jobs_helper_test.rb deleted file mode 100644 index 9d64b7d832..0000000000 --- a/services/api/test/unit/helpers/jobs_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class JobsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/keep_disks_helper_test.rb b/services/api/test/unit/helpers/keep_disks_helper_test.rb deleted file mode 100644 index 9dcc619df5..0000000000 --- a/services/api/test/unit/helpers/keep_disks_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class KeepDisksHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/links_helper_test.rb b/services/api/test/unit/helpers/links_helper_test.rb deleted file mode 100644 index 918f145ff6..0000000000 --- a/services/api/test/unit/helpers/links_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class LinksHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/logs_helper_test.rb b/services/api/test/unit/helpers/logs_helper_test.rb deleted file mode 100644 index 616f6e664b..0000000000 --- a/services/api/test/unit/helpers/logs_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class LogsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/nodes_helper_test.rb b/services/api/test/unit/helpers/nodes_helper_test.rb deleted file mode 100644 index 8a92eb990d..0000000000 --- a/services/api/test/unit/helpers/nodes_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class NodesHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/pipeline_instances_helper_test.rb b/services/api/test/unit/helpers/pipeline_instances_helper_test.rb deleted file mode 100644 index 9d3b5c48f1..0000000000 --- a/services/api/test/unit/helpers/pipeline_instances_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class PipelineInstancesHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/pipeline_templates_helper_test.rb b/services/api/test/unit/helpers/pipeline_templates_helper_test.rb deleted file mode 100644 index 9a9a4179d6..0000000000 --- a/services/api/test/unit/helpers/pipeline_templates_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class PipelinesHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/repositories_helper_test.rb b/services/api/test/unit/helpers/repositories_helper_test.rb deleted file mode 100644 index 33cb590513..0000000000 --- a/services/api/test/unit/helpers/repositories_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class RepositoriesHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/specimens_helper_test.rb b/services/api/test/unit/helpers/specimens_helper_test.rb deleted file mode 100644 index 3709198065..0000000000 --- a/services/api/test/unit/helpers/specimens_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class SpecimensHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/traits_helper_test.rb b/services/api/test/unit/helpers/traits_helper_test.rb deleted file mode 100644 index 03b6a97f41..0000000000 --- a/services/api/test/unit/helpers/traits_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class TraitsHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/helpers/virtual_machines_helper_test.rb b/services/api/test/unit/helpers/virtual_machines_helper_test.rb deleted file mode 100644 index 99fc258cb4..0000000000 --- a/services/api/test/unit/helpers/virtual_machines_helper_test.rb +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class VirtualMachinesHelperTest < ActionView::TestCase -end diff --git a/services/api/test/unit/human_test.rb b/services/api/test/unit/human_test.rb deleted file mode 100644 index 83cc40e686..0000000000 --- a/services/api/test/unit/human_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class HumanTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/services/api/test/unit/job_task_test.rb b/services/api/test/unit/job_task_test.rb deleted file mode 100644 index 36a0e723f2..0000000000 --- a/services/api/test/unit/job_task_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class JobTaskTest < ActiveSupport::TestCase - -end diff --git a/services/api/test/unit/job_test.rb b/services/api/test/unit/job_test.rb deleted file mode 100644 index 815079f8af..0000000000 --- a/services/api/test/unit/job_test.rb +++ /dev/null @@ -1,277 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' -require 'helpers/git_test_helper' -require 'helpers/docker_migration_helper' - -class JobTest < ActiveSupport::TestCase - include DockerMigrationHelper - include GitTestHelper - - BAD_COLLECTION = "#{'f' * 32}+0" - - setup do - set_user_from_auth :active - end - - def job_attrs merge_me={} - # Default (valid) set of attributes, with given overrides - { - script: "hash", - script_version: "main", - repository: "active/foo", - }.merge(merge_me) - end - - test "Job without Docker image doesn't get locator" do - job = Job.new job_attrs - assert job.valid?, job.errors.full_messages.to_s - assert_nil job.docker_image_locator - end - - { 'name' => [:links, :docker_image_collection_tag, :name], - 'hash' => [:links, :docker_image_collection_hash, :name], - 'locator' => [:collections, :docker_image, :portable_data_hash], - }.each_pair do |spec_type, (fixture_type, fixture_name, fixture_attr)| - test "Job initialized with Docker image #{spec_type} gets locator" do - image_spec = send(fixture_type, fixture_name).send(fixture_attr) - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_spec}) - assert job.valid?, job.errors.full_messages.to_s - assert_equal(collections(:docker_image).portable_data_hash, job.docker_image_locator) - end - - test "Job modified with Docker image #{spec_type} gets locator" do - job = Job.new job_attrs - assert job.valid?, job.errors.full_messages.to_s - assert_nil job.docker_image_locator - image_spec = send(fixture_type, fixture_name).send(fixture_attr) - job.runtime_constraints['docker_image'] = image_spec - assert job.valid?, job.errors.full_messages.to_s - assert_equal(collections(:docker_image).portable_data_hash, job.docker_image_locator) - end - end - - test "removing a Docker runtime constraint removes the locator" do - image_locator = collections(:docker_image).portable_data_hash - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_locator}) - assert job.valid?, job.errors.full_messages.to_s - assert_equal(image_locator, job.docker_image_locator) - job.runtime_constraints = {} - assert job.valid?, job.errors.full_messages.to_s + "after clearing runtime constraints" - assert_nil job.docker_image_locator - end - - test "locate a Docker image with a repository + tag" do - image_repo, image_tag = - links(:docker_image_collection_tag2).name.split(':', 2) - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_repo, - 'docker_image_tag' => image_tag}) - assert job.valid?, job.errors.full_messages.to_s - assert_equal(collections(:docker_image).portable_data_hash, job.docker_image_locator) - end - - test "can't locate a Docker image with a nonexistent tag" do - image_repo = links(:docker_image_collection_tag).name - image_tag = '__nonexistent tag__' - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_repo, - 'docker_image_tag' => image_tag}) - assert(job.invalid?, "Job with bad Docker tag valid") - end - - [ - false, - true - ].each do |use_config| - test "Job with no Docker image uses default docker image when configuration is set #{use_config}" do - default_docker_image = collections(:docker_image)[:portable_data_hash] - Rails.configuration.Containers.JobsAPI.DefaultDockerImage = default_docker_image if use_config - - job = Job.new job_attrs - assert job.valid?, job.errors.full_messages.to_s - - if use_config - refute_nil job.docker_image_locator - assert_equal default_docker_image, job.docker_image_locator - else - assert_nil job.docker_image_locator - end - end - end - - test "locate a Docker image with a partial hash" do - image_hash = links(:docker_image_collection_hash).name[0..24] - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_hash}) - assert job.valid?, job.errors.full_messages.to_s + " with partial hash #{image_hash}" - assert_equal(collections(:docker_image).portable_data_hash, job.docker_image_locator) - end - - { 'name' => 'arvados_test_nonexistent', - 'hash' => 'f' * 64, - 'locator' => BAD_COLLECTION, - }.each_pair do |spec_type, image_spec| - test "Job validation fails with nonexistent Docker image #{spec_type}" do - Rails.configuration.RemoteClusters = ConfigLoader.to_OrderedOptions({}) - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => image_spec}) - assert(job.invalid?, "nonexistent Docker image #{spec_type} #{image_spec} was valid") - end - end - - test "Job validation fails with non-Docker Collection constraint" do - job = Job.new job_attrs(runtime_constraints: - {'docker_image' => collections(:foo_file).uuid}) - assert(job.invalid?, "non-Docker Collection constraint was valid") - end - - test "can create Job with Docker image Collection without Docker links" do - image_uuid = collections(:unlinked_docker_image).portable_data_hash - job = Job.new job_attrs(runtime_constraints: {"docker_image" => image_uuid}) - assert(job.valid?, "Job created with unlinked Docker image was invalid") - assert_equal(image_uuid, job.docker_image_locator) - end - - def check_attrs_unset(job, attrs) - assert_empty(attrs.each_key.map { |key| job.send(key) }.compact, - "job has values for #{attrs.keys}") - end - - def check_creation_prohibited(attrs) - begin - job = Job.new(job_attrs(attrs)) - rescue ActiveModel::MassAssignmentSecurity::Error - # Test passes - expected attribute protection - else - check_attrs_unset(job, attrs) - end - end - - def check_modification_prohibited(attrs) - job = Job.new(job_attrs) - attrs.each_pair do |key, value| - assert_raises(NoMethodError) { job.send("{key}=".to_sym, value) } - end - check_attrs_unset(job, attrs) - end - - test "can't create Job with Docker image locator" do - check_creation_prohibited(docker_image_locator: BAD_COLLECTION) - end - - test "can't assign Docker image locator to Job" do - check_modification_prohibited(docker_image_locator: BAD_COLLECTION) - end - - SDK_MASTER = "ca68b24e51992e790f29df5cc4bc54ce1da4a1c2" - SDK_TAGGED = "00634b2b8a492d6f121e3cf1d6587b821136a9a7" - - def sdk_constraint(version) - {runtime_constraints: { - "arvados_sdk_version" => version, - "docker_image" => links(:docker_image_collection_tag).name, - }} - end - - def check_job_sdk_version(expected) - job = yield - if expected.nil? - refute(job.valid?, "job valid with bad Arvados SDK version") - else - assert(job.valid?, "job not valid with good Arvados SDK version") - assert_equal(expected, job.arvados_sdk_version) - end - end - - test "can't create job with SDK version assigned directly" do - check_creation_prohibited(arvados_sdk_version: SDK_MASTER) - end - - test "can't modify job to assign SDK version directly" do - check_modification_prohibited(arvados_sdk_version: SDK_MASTER) - end - - test 'script_parameters_digest is independent of key order' do - j1 = Job.new(job_attrs(script_parameters: {'a' => 'a', 'ddee' => {'d' => 'd', 'e' => 'e'}})) - j2 = Job.new(job_attrs(script_parameters: {'ddee' => {'e' => 'e', 'd' => 'd'}, 'a' => 'a'})) - assert j1.valid? - assert j2.valid? - assert_equal(j1.script_parameters_digest, j2.script_parameters_digest) - end - - test 'job fixtures have correct script_parameters_digest' do - Job.all.each do |j| - d = j.script_parameters_digest - assert_equal(j.update_script_parameters_digest, d, - "wrong script_parameters_digest for #{j.uuid}") - end - end - - test 'deep_sort_hash on array of hashes' do - a = {'z' => [[{'a' => 'a', 'b' => 'b'}]]} - b = {'z' => [[{'b' => 'b', 'a' => 'a'}]]} - assert_equal Job.deep_sort_hash(a).to_json, Job.deep_sort_hash(b).to_json - end - - def try_find_reusable - foobar = jobs(:foobar) - example_attrs = { - script_version: foobar.script_version, - script: foobar.script, - script_parameters: foobar.script_parameters, - repository: foobar.repository, - } - - # Two matching jobs exist with identical outputs. The older one - # should be reused. - j = Job.find_reusable(example_attrs, {}, [], [users(:active)]) - assert j - assert_equal foobar.uuid, j.uuid - - # Two matching jobs exist with different outputs. Neither should - # be reused. - Job.where(uuid: jobs(:job_with_latest_version).uuid). - update_all(output: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+1') - assert_nil Job.find_reusable(example_attrs, {}, [], [users(:active)]) - - # ...unless config says to reuse the earlier job in such cases. - Rails.configuration.Containers.JobsAPI.ReuseJobIfOutputsDiffer = true - j = Job.find_reusable(example_attrs, {}, [], [users(:active)]) - assert_equal foobar.uuid, j.uuid - end - - test 'enable legacy api configuration option = true' do - Rails.configuration.Containers.JobsAPI.Enable = "true" - check_enable_legacy_jobs_api - assert_equal(Disable_update_jobs_api_method_list, Rails.configuration.API.DisabledAPIs) - end - - test 'enable legacy api configuration option = false' do - Rails.configuration.Containers.JobsAPI.Enable = "false" - check_enable_legacy_jobs_api - assert_equal Disable_jobs_api_method_list, Rails.configuration.API.DisabledAPIs - end - - test 'enable legacy api configuration option = auto, has jobs' do - Rails.configuration.Containers.JobsAPI.Enable = "auto" - assert Job.count > 0 - check_enable_legacy_jobs_api - assert_equal(Disable_update_jobs_api_method_list, Rails.configuration.API.DisabledAPIs) - end - - test 'enable legacy api configuration option = auto, no jobs' do - Rails.configuration.Containers.JobsAPI.Enable = "auto" - act_as_system_user do - Job.destroy_all - end - assert_equal 0, Job.count - assert_equal({}, Rails.configuration.API.DisabledAPIs) - check_enable_legacy_jobs_api - assert_equal Disable_jobs_api_method_list, Rails.configuration.API.DisabledAPIs - end -end diff --git a/services/api/test/unit/link_test.rb b/services/api/test/unit/link_test.rb index b9806486ad..fb0d028337 100644 --- a/services/api/test/unit/link_test.rb +++ b/services/api/test/unit/link_test.rb @@ -13,7 +13,7 @@ class LinkTest < ActiveSupport::TestCase test "cannot delete an object referenced by unwritable links" do ob = act_as_user users(:active) do - Specimen.create + Collection.create end link = act_as_user users(:admin) do Link.create(tail_uuid: users(:active).uuid, diff --git a/services/api/test/unit/log_test.rb b/services/api/test/unit/log_test.rb index d3a1b618d5..e69f0517e4 100644 --- a/services/api/test/unit/log_test.rb +++ b/services/api/test/unit/log_test.rb @@ -32,6 +32,10 @@ class LogTest < ActiveSupport::TestCase Log.where(object_uuid: thing.uuid).order("created_at ASC").all end + def clear_logs_about(thing) + Log.where(object_uuid: thing.uuid).delete_all + end + def assert_logged(thing, event_type) logs = get_logs_about(thing) assert_equal(@log_count, logs.size, "log count mismatch") @@ -106,10 +110,11 @@ class LogTest < ActiveSupport::TestCase test "old_attributes preserves values deep inside a hash" do set_user_from_auth :active - it = specimens(:owned_by_active_user) + it = collections(:collection_owned_by_active) + clear_logs_about it it.properties = {'foo' => {'bar' => ['baz', 'qux', {'quux' => 'bleat'}]}} it.save! - @log_count += 1 + assert_logged it, :update it.properties['foo']['bar'][2]['quux'] = 'blert' it.save! assert_logged it, :update do |props| @@ -231,6 +236,7 @@ class LogTest < ActiveSupport::TestCase test "don't log changes only to Collection.preserve_version" do set_user_from_auth :admin_trustedclient col = collections(:collection_owned_by_active) + clear_logs_about col start_log_count = get_logs_about(col).size assert_equal false, col.preserve_version col.preserve_version = true @@ -258,27 +264,29 @@ class LogTest < ActiveSupport::TestCase test "use ownership and permission links to determine which logs a user can see" do known_logs = [:noop, - :admin_changes_repository2, - :admin_changes_specimen, + :admin_changes_collection_owned_by_active, + :admin_changes_collection_owned_by_foo, :system_adds_foo_file, :system_adds_baz, :log_owned_by_active, - :crunchstat_for_running_job] + :crunchstat_for_running_container] c = Log.readable_by(users(:admin)).order("id asc").each.to_a assert_log_result c, known_logs, known_logs c = Log.readable_by(users(:active)).order("id asc").each.to_a - assert_log_result c, known_logs, [:admin_changes_repository2, # owned by active - :system_adds_foo_file, # readable via link - :system_adds_baz, # readable via 'all users' group - :log_owned_by_active, # log owned by active - :crunchstat_for_running_job] # log & job owned by active + assert_log_result c, known_logs, [:admin_changes_collection_owned_by_active, + :system_adds_foo_file, # readable via link + :system_adds_baz, # readable via 'all users' group + :log_owned_by_active, # log owned by active + :crunchstat_for_running_container] # log & job owned by active c = Log.readable_by(users(:spectator)).order("id asc").each.to_a - assert_log_result c, known_logs, [:noop, # object_uuid is spectator - :admin_changes_specimen, # object_uuid is a specimen owned by spectator - :system_adds_baz] # readable via 'all users' group + assert_log_result c, known_logs, [:noop, # object_uuid is spectator + :system_adds_baz] # readable via 'all users' group + + c = Log.readable_by(users(:user_foo_in_sharing_group)).order("id asc").each.to_a + assert_log_result c, known_logs, [:admin_changes_collection_owned_by_foo] # collection's parent is readable via role group end def assert_log_result result, known_logs, expected_logs diff --git a/services/api/test/unit/owner_test.rb b/services/api/test/unit/owner_test.rb index 1c1bd93b81..a96170c716 100644 --- a/services/api/test/unit/owner_test.rb +++ b/services/api/test/unit/owner_test.rb @@ -11,7 +11,7 @@ require 'test_helper' # "i" is an item. class OwnerTest < ActiveSupport::TestCase - fixtures :users, :groups, :specimens + fixtures :users, :groups setup do set_user_from_auth :admin_trustedclient @@ -26,22 +26,22 @@ class OwnerTest < ActiveSupport::TestCase else o = o_class.create! end - i = Specimen.create(owner_uuid: o.uuid) + i = Collection.create(owner_uuid: o.uuid) assert i.valid?, "new item should pass validation" assert i.uuid, "new item should have an ID" - assert Specimen.where(uuid: i.uuid).any?, "new item should really be in DB" + assert Collection.where(uuid: i.uuid).any?, "new item should really be in DB" end test "create object with non-existent #{o_class} owner" do assert_raises(ActiveRecord::RecordInvalid, "create should fail with random owner_uuid") do - Specimen.create!(owner_uuid: o_class.generate_uuid) + Collection.create!(owner_uuid: o_class.generate_uuid) end - i = Specimen.create(owner_uuid: o_class.generate_uuid) + i = Collection.create(owner_uuid: o_class.generate_uuid) assert !i.valid?, "object with random owner_uuid should not be valid?" - i = Specimen.new(owner_uuid: o_class.generate_uuid) + i = Collection.new(owner_uuid: o_class.generate_uuid) assert !i.valid?, "new item should not pass validation" assert !i.uuid, "new item should not have an ID" end @@ -53,7 +53,7 @@ class OwnerTest < ActiveSupport::TestCase else o_class.create! end - i = Specimen.create!(owner_uuid: o.uuid) + i = Collection.create!(owner_uuid: o.uuid) new_o = if new_o_class == Group new_o_class.create! group_class: "project" @@ -61,7 +61,7 @@ class OwnerTest < ActiveSupport::TestCase new_o_class.create! end - assert(Specimen.where(uuid: i.uuid).any?, + assert(Collection.where(uuid: i.uuid).any?, "new item should really be in DB") assert(i.update(owner_uuid: new_o.uuid), "should change owner_uuid from #{o.uuid} to #{new_o.uuid}") @@ -102,7 +102,7 @@ class OwnerTest < ActiveSupport::TestCase ['users(:active)', 'groups(:aproject)'].each do |ofixt| test "delete #{ofixt} that owns other objects" do o = eval ofixt - assert_equal(true, Specimen.where(owner_uuid: o.uuid).any?, + assert_equal(true, Collection.where(owner_uuid: o.uuid).any?, "need something to be owned by #{o.uuid} for this test") skip_check_permissions_against_full_refresh do @@ -115,7 +115,7 @@ class OwnerTest < ActiveSupport::TestCase test "change uuid of #{ofixt} that owns other objects" do o = eval ofixt - assert_equal(true, Specimen.where(owner_uuid: o.uuid).any?, + assert_equal(true, Collection.where(owner_uuid: o.uuid).any?, "need something to be owned by #{o.uuid} for this test") new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9]) assert(!o.update(uuid: new_uuid), diff --git a/services/api/test/unit/permission_test.rb b/services/api/test/unit/permission_test.rb index 14c810d81a..3059896061 100644 --- a/services/api/test/unit/permission_test.rb +++ b/services/api/test/unit/permission_test.rb @@ -222,7 +222,7 @@ class PermissionTest < ActiveSupport::TestCase Rails.configuration.Users.ActivatedUsersAreVisibleToOthers = false manager = create :active_user, first_name: "Manage", last_name: "Er" minion = create :active_user, first_name: "Min", last_name: "Ion" - minions_specimen = act_as_user minion do + minions_collection = act_as_user minion do g = Group.create! name: "minon project", group_class: "project" Collection.create! owner_uuid: g.uuid end @@ -289,11 +289,11 @@ class PermissionTest < ActiveSupport::TestCase end assert_empty(Collection .readable_by(manager) - .where(uuid: minions_specimen.uuid), + .where(uuid: minions_collection.uuid), "manager saw the minion's private stuff") assert_raises(ArvadosModel::PermissionDeniedError, "manager could update minion's private stuff") do - minions_specimen.update(properties: {'x' => 'y'}) + minions_collection.update(properties: {'x' => 'y'}) end end @@ -307,11 +307,11 @@ class PermissionTest < ActiveSupport::TestCase # Now, manager can read and write Minion's stuff. assert_not_empty(Collection .readable_by(manager) - .where(uuid: minions_specimen.uuid), - "manager could not find minion's specimen by uuid") + .where(uuid: minions_collection.uuid), + "manager could not find minion's collection by uuid") assert_equal(true, - minions_specimen.update(properties: {'x' => 'y'}), - "manager could not update minion's specimen object") + minions_collection.update(properties: {'x' => 'y'}), + "manager could not update minion's collection object") end end @@ -341,12 +341,12 @@ class PermissionTest < ActiveSupport::TestCase assert_not_empty(User.readable_by(a).where(uuid: b.uuid), "#{a.first_name} should be able to see 'b' in the user list") - a_specimen = act_as_user a do + a_collection = act_as_user a do Collection.create! end - assert_not_empty(Collection.readable_by(a).where(uuid: a_specimen.uuid), + assert_not_empty(Collection.readable_by(a).where(uuid: a_collection.uuid), "A cannot read own Collection, following test probably useless.") - assert_empty(Collection.readable_by(b).where(uuid: a_specimen.uuid), + assert_empty(Collection.readable_by(b).where(uuid: a_collection.uuid), "B can read A's Collection") [a,b].each do |u| assert_empty(User.readable_by(u).where(uuid: other.uuid), diff --git a/services/api/test/unit/pipeline_instance_test.rb b/services/api/test/unit/pipeline_instance_test.rb deleted file mode 100644 index 614c169e85..0000000000 --- a/services/api/test/unit/pipeline_instance_test.rb +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class PipelineInstanceTest < ActiveSupport::TestCase - - [:has_component_with_no_script_parameters, - :has_component_with_empty_script_parameters].each do |pi_name| - test "update pipeline that #{pi_name}" do - pi = pipeline_instances pi_name - - Thread.current[:user] = users(:active) - assert_equal PipelineInstance::Ready, pi.state - end - end -end diff --git a/services/api/test/unit/pipeline_template_test.rb b/services/api/test/unit/pipeline_template_test.rb deleted file mode 100644 index 8ead613b80..0000000000 --- a/services/api/test/unit/pipeline_template_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class PipelineTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/services/api/test/unit/repository_test.rb b/services/api/test/unit/repository_test.rb deleted file mode 100644 index 674a34ffd8..0000000000 --- a/services/api/test/unit/repository_test.rb +++ /dev/null @@ -1,283 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' -require 'helpers/git_test_helper' - -class RepositoryTest < ActiveSupport::TestCase - include GitTestHelper - - def new_repo(owner_key, attrs={}) - set_user_from_auth owner_key - owner = users(owner_key) - Repository.new({owner_uuid: owner.uuid}.merge(attrs)) - end - - def changed_repo(repo_key, changes) - repo = repositories(repo_key) - changes.each_pair { |attr, value| repo.send("#{attr}=".to_sym, value) } - repo - end - - def default_git_url(repo_name, user_name=nil) - if user_name - "git@git.%s.arvadosapi.com:%s/%s.git" % - [Rails.configuration.ClusterID, user_name, repo_name] - else - "git@git.%s.arvadosapi.com:%s.git" % - [Rails.configuration.ClusterID, repo_name] - end - end - - def assert_server_path(path_tail, repo_sym) - assert_equal(File.join(Rails.configuration.Git.Repositories, path_tail), - repositories(repo_sym).server_path) - end - - ### name validation - - {active: "active/", admin: "admin/", system_user: ""}. - each_pair do |user_sym, name_prefix| - test "valid names for #{user_sym} repo" do - %w(a aa a0 aA Aa AA A0).each do |name| - repo = new_repo(user_sym, name: name_prefix + name) - assert(repo.valid?) - end - end - - test "name is required for #{user_sym} repo" do - refute(new_repo(user_sym).valid?) - end - - test "repo name beginning with numeral is invalid for #{user_sym}" do - repo = new_repo(user_sym, name: "#{name_prefix}0a") - refute(repo.valid?) - end - - test "name containing bad char is invalid for #{user_sym}" do - "\\.-_/!@#$%^&*()[]{}".each_char do |bad_char| - repo = new_repo(user_sym, name: "#{name_prefix}bad#{bad_char}reponame") - refute(repo.valid?) - end - end - end - - test "admin can create valid repo for other user with correct name prefix" do - owner = users(:active) - repo = new_repo(:admin, name: "#{owner.username}/validnametest", - owner_uuid: owner.uuid) - assert(repo.valid?) - end - - test "admin can create valid system repo without name prefix" do - repo = new_repo(:admin, name: "validnametest", - owner_uuid: users(:system_user).uuid) - assert(repo.valid?) - end - - test "repo name prefix must match owner_uuid username" do - repo = new_repo(:admin, name: "admin/badusernametest", - owner_uuid: users(:active).uuid) - refute(repo.valid?) - end - - test "repo name prefix must be empty for system repo" do - repo = new_repo(:admin, name: "root/badprefixtest", - owner_uuid: users(:system_user).uuid) - refute(repo.valid?) - end - - ### owner validation - - test "name must be unique per user" do - repo = new_repo(:active, name: repositories(:foo).name) - refute(repo.valid?) - end - - test "name can be duplicated across users" do - repo = new_repo(:active, name: "active/#{repositories(:arvados).name}") - assert(repo.valid?) - end - - test "repository cannot be owned by a group" do - set_user_from_auth :active - repo = Repository.new(owner_uuid: groups(:all_users).uuid, - name: "ownedbygroup") - refute(repo.valid?) - refute_empty(repo.errors[:owner_uuid] || []) - end - - ### URL generation - - test "fetch_url" do - repo = new_repo(:active, name: "active/fetchtest") - repo.save - assert_equal(default_git_url("fetchtest", "active"), repo.fetch_url) - end - - test "fetch_url owned by system user" do - set_user_from_auth :admin - repo = Repository.new(owner_uuid: users(:system_user).uuid, - name: "fetchtest") - repo.save - assert_equal(default_git_url("fetchtest"), repo.fetch_url) - end - - test "push_url" do - repo = new_repo(:active, name: "active/pushtest") - repo.save - assert_equal(default_git_url("pushtest", "active"), repo.push_url) - end - - test "push_url owned by system user" do - set_user_from_auth :admin - repo = Repository.new(owner_uuid: users(:system_user).uuid, - name: "pushtest") - repo.save - assert_equal(default_git_url("pushtest"), repo.push_url) - end - - ### Path generation - - test "disk path stored by UUID" do - assert_server_path("zzzzz-s0uqq-382brsig8rp3666/.git", :foo) - end - - test "disk path stored by name" do - assert_server_path("arvados/.git", :arvados) - end - - test "disk path for repository not on disk" do - assert_nil(Repository.new.server_path) - end - - ### Repository creation - - test "non-admin can create a repository for themselves" do - repo = new_repo(:active, name: "active/newtestrepo") - assert(repo.save) - end - - test "non-admin can't create a repository for another visible user" do - repo = new_repo(:active, name: "repoforanon", - owner_uuid: users(:anonymous).uuid) - assert_not_allowed { repo.save } - end - - test "admin can create a repository for themselves" do - repo = new_repo(:admin, name: "admin/newtestrepo") - assert(repo.save) - end - - test "admin can create a repository for others" do - repo = new_repo(:admin, name: "active/repoforactive", - owner_uuid: users(:active).uuid) - assert(repo.save) - end - - test "admin can create a system repository" do - repo = new_repo(:admin, name: "repoforsystem", - owner_uuid: users(:system_user).uuid) - assert(repo.save) - end - - ### Repository destruction - - test "non-admin can destroy their own repository" do - set_user_from_auth :active - assert(repositories(:foo).destroy) - end - - test "non-admin can't destroy others' repository" do - set_user_from_auth :active - assert_not_allowed { repositories(:repository3).destroy } - end - - test "non-admin can't destroy system repository" do - set_user_from_auth :active - assert_not_allowed { repositories(:arvados).destroy } - end - - test "admin can destroy their own repository" do - set_user_from_auth :admin - assert(repositories(:repository3).destroy) - end - - test "admin can destroy others' repository" do - set_user_from_auth :admin - assert(repositories(:foo).destroy) - end - - test "admin can destroy system repository" do - set_user_from_auth :admin - assert(repositories(:arvados).destroy) - end - - ### Changing ownership - - test "non-admin can't make their repository a system repository" do - set_user_from_auth :active - repo = changed_repo(:foo, owner_uuid: users(:system_user).uuid) - assert_not_allowed { repo.save } - end - - test "admin can give their repository to someone else" do - set_user_from_auth :admin - repo = changed_repo(:repository3, owner_uuid: users(:active).uuid, - name: "active/foo3") - assert(repo.save) - end - - test "admin can make their repository a system repository" do - set_user_from_auth :admin - repo = changed_repo(:repository3, owner_uuid: users(:system_user).uuid, - name: "foo3") - assert(repo.save) - end - - test 'write permission allows changing modified_at' do - act_as_user users(:active) do - r = repositories(:foo) - modtime_was = r.modified_at - r.modified_at = Time.now - assert r.save - assert_operator modtime_was, :<, r.modified_at - end - end - - test 'write permission necessary for changing modified_at' do - act_as_user users(:spectator) do - r = repositories(:foo) - modtime_was = r.modified_at - r.modified_at = Time.now - assert_raises ArvadosModel::PermissionDeniedError do - r.save! - end - r.reload - assert_equal modtime_was, r.modified_at - end - end - - ### Renaming - - test "non-admin can rename own repo" do - act_as_user users(:active) do - assert repositories(:foo).update(name: 'active/foo12345') - end - end - - test "top level repo can be touched by non-admin with can_manage" do - add_permission_link users(:active), repositories(:arvados), 'can_manage' - act_as_user users(:active) do - assert changed_repo(:arvados, modified_at: Time.now).save - end - end - - test "top level repo cannot be renamed by non-admin with can_manage" do - add_permission_link users(:active), repositories(:arvados), 'can_manage' - act_as_user users(:active) do - assert_not_allowed { changed_repo(:arvados, name: 'xarvados').save } - end - end -end diff --git a/services/api/test/unit/specimen_test.rb b/services/api/test/unit/specimen_test.rb deleted file mode 100644 index 5b2eda2f0f..0000000000 --- a/services/api/test/unit/specimen_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class SpecimenTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/services/api/test/unit/trait_test.rb b/services/api/test/unit/trait_test.rb deleted file mode 100644 index fe63f161f8..0000000000 --- a/services/api/test/unit/trait_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -require 'test_helper' - -class TraitTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end diff --git a/services/api/test/unit/user_test.rb b/services/api/test/unit/user_test.rb index 810e5b45ec..71b5769be8 100644 --- a/services/api/test/unit/user_test.rb +++ b/services/api/test/unit/user_test.rb @@ -118,18 +118,7 @@ class UserTest < ActiveSupport::TestCase check_new_username_setting("_", nil) end - test "updating username updates repository names" do - set_user_from_auth :admin - user = users(:active) - user.username = "newtestname" - assert(user.save, "username update failed") - {foo: "newtestname/foo", repository2: "newtestname/foo2"}. - each_pair do |repo_sym, expect_name| - assert_equal(expect_name, repositories(repo_sym).name) - end - end - - test "admin can clear username when user owns no repositories" do + test "admin can clear username" do set_user_from_auth :admin user = users(:spectator) user.username = nil @@ -137,22 +126,6 @@ class UserTest < ActiveSupport::TestCase assert_nil(user.username) end - test "admin can't clear username when user owns repositories" do - set_user_from_auth :admin - user = users(:active) - user.username = nil - assert_not_allowed { user.save } - refute_empty(user.errors[:username]) - end - - test "failed username update doesn't change repository names" do - set_user_from_auth :admin - user = users(:active) - user.username = users(:fuse).username - assert_not_allowed { user.save } - assert_equal("active/foo", repositories(:foo).name) - end - [[false, 'foo@example.com', true, false], [false, 'bar@example.com', false, true], [true, 'foo@example.com', true, false], @@ -359,37 +332,33 @@ class UserTest < ActiveSupport::TestCase [ # Easy inactive user tests. - [false, empty_notify_list, empty_notify_list, "inactive-none@example.com", false, false, "inactivenone"], - [false, empty_notify_list, empty_notify_list, "inactive-vm@example.com", true, false, "inactivevm"], - [false, empty_notify_list, empty_notify_list, "inactive-repo@example.com", false, true, "inactiverepo"], - [false, empty_notify_list, empty_notify_list, "inactive-both@example.com", true, true, "inactiveboth"], + [false, empty_notify_list, empty_notify_list, "inactive-none@example.com", false, "inactivenone"], + [false, empty_notify_list, empty_notify_list, "inactive-vm@example.com", true, "inactivevm"], # Easy active user tests. - [true, active_notify_list, inactive_notify_list, "active-none@example.com", false, false, "activenone"], - [true, active_notify_list, inactive_notify_list, "active-vm@example.com", true, false, "activevm"], - [true, active_notify_list, inactive_notify_list, "active-repo@example.com", false, true, "activerepo"], - [true, active_notify_list, inactive_notify_list, "active-both@example.com", true, true, "activeboth"], + [true, active_notify_list, inactive_notify_list, "active-none@example.com", false, "activenone"], + [true, active_notify_list, inactive_notify_list, "active-vm@example.com", true, "activevm"], # Test users with malformed e-mail addresses. - [false, empty_notify_list, empty_notify_list, nil, true, true, nil], - [false, empty_notify_list, empty_notify_list, "arvados", true, true, nil], - [false, empty_notify_list, empty_notify_list, "@example.com", true, true, nil], - [true, active_notify_list, inactive_notify_list, "*!*@example.com", true, false, nil], - [true, active_notify_list, inactive_notify_list, "*!*@example.com", false, false, nil], + [false, empty_notify_list, empty_notify_list, nil, true, nil], + [false, empty_notify_list, empty_notify_list, "arvados", true, nil], + [false, empty_notify_list, empty_notify_list, "@example.com", true, nil], + [true, active_notify_list, inactive_notify_list, "*!*@example.com", true, nil], + [true, active_notify_list, inactive_notify_list, "*!*@example.com", false, nil], # Test users with various username transformations. - [false, empty_notify_list, empty_notify_list, "arvados@example.com", false, false, "arvados2"], - [true, active_notify_list, inactive_notify_list, "arvados@example.com", false, false, "arvados2"], - [true, active_notify_list, inactive_notify_list, "root@example.com", true, false, "root2"], - [false, active_notify_list, empty_notify_list, "root@example.com", true, false, "root2"], - [true, active_notify_list, inactive_notify_list, "roo_t@example.com", false, true, "root2"], - [false, empty_notify_list, empty_notify_list, "^^incorrect_format@example.com", true, true, "incorrectformat"], - [true, active_notify_list, inactive_notify_list, "&4a_d9.@example.com", true, true, "ad9"], - [true, active_notify_list, inactive_notify_list, "&4a_d9.@example.com", false, false, "ad9"], - [false, active_notify_list, empty_notify_list, "&4a_d9.@example.com", true, true, "ad9"], - [false, active_notify_list, empty_notify_list, "&4a_d9.@example.com", false, false, "ad9"], - ].each do |active, new_user_recipients, inactive_recipients, email, auto_setup_vm, auto_setup_repo, expect_username| - test "create new user with auto setup active=#{active} email=#{email} vm=#{auto_setup_vm} repo=#{auto_setup_repo}" do + [false, empty_notify_list, empty_notify_list, "arvados@example.com", false, "arvados2"], + [true, active_notify_list, inactive_notify_list, "arvados@example.com", false, "arvados2"], + [true, active_notify_list, inactive_notify_list, "root@example.com", true, "root2"], + [false, active_notify_list, empty_notify_list, "root@example.com", true, "root2"], + [true, active_notify_list, inactive_notify_list, "roo_t@example.com", false, "root2"], + [false, empty_notify_list, empty_notify_list, "^^incorrect_format@example.com", true, "incorrectformat"], + [true, active_notify_list, inactive_notify_list, "&4a_d9.@example.com", true, "ad9"], + [true, active_notify_list, inactive_notify_list, "&4a_d9.@example.com", false, "ad9"], + [false, active_notify_list, empty_notify_list, "&4a_d9.@example.com", true, "ad9"], + [false, active_notify_list, empty_notify_list, "&4a_d9.@example.com", false, "ad9"], + ].each do |active, new_user_recipients, inactive_recipients, email, auto_setup_vm, expect_username| + test "create new user with auto setup active=#{active} email=#{email} vm=#{auto_setup_vm}" do set_user_from_auth :admin Rails.configuration.Users.AutoSetupNewUsers = true @@ -400,8 +369,6 @@ class UserTest < ActiveSupport::TestCase Rails.configuration.Users.AutoSetupNewUsersWithVmUUID = "" end - Rails.configuration.Users.AutoSetupNewUsersWithRepository = auto_setup_repo - create_user_and_verify_setup_and_notifications active, new_user_recipients, inactive_recipients, email, expect_username end end @@ -460,8 +427,7 @@ class UserTest < ActiveSupport::TestCase vm = VirtualMachine.create - response = user.setup(repo_name: 'foo/testrepo', - vm_uuid: vm.uuid) + response = user.setup(vm_uuid: vm.uuid) resp_user = find_obj_in_resp response, 'User' verify_user resp_user, email @@ -476,9 +442,6 @@ class UserTest < ActiveSupport::TestCase assert_nil group_perm2 end - repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository' - verify_link repo_perm, 'permission', 'can_manage', resp_user[:uuid], nil - vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine' verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid assert_equal("foo", vm_perm.properties["username"]) @@ -494,8 +457,7 @@ class UserTest < ActiveSupport::TestCase vm = VirtualMachine.create - response = user.setup(repo_name: 'foo/testrepo', - vm_uuid: vm.uuid) + response = user.setup(vm_uuid: vm.uuid) resp_user = find_obj_in_resp response, 'User' verify_user resp_user, email @@ -503,9 +465,6 @@ class UserTest < ActiveSupport::TestCase group_perm = find_obj_in_resp response, 'Link', 'arvados#group' verify_link group_perm, 'permission', 'can_write', resp_user[:uuid], groups(:all_users).uuid - repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository' - verify_link repo_perm, 'permission', 'can_manage', resp_user[:uuid], nil - vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine' verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid assert_equal("foo", vm_perm.properties["username"]) @@ -529,23 +488,10 @@ class UserTest < ActiveSupport::TestCase group_perm2 = find_obj_in_resp response, 'Link', 'arvados#user' verify_link group_perm2, 'permission', 'can_read', groups(:all_users).uuid, nil - # invoke setup again with repo_name - response = user.setup(repo_name: 'foo/testrepo') - resp_user = find_obj_in_resp response, 'User', nil - verify_user resp_user, email - assert_equal user.uuid, resp_user[:uuid], 'expected uuid not found' - - group_perm = find_obj_in_resp response, 'Link', 'arvados#group' - verify_link group_perm, 'permission', 'can_write', resp_user[:uuid], groups(:all_users).uuid - - repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository' - verify_link repo_perm, 'permission', 'can_manage', resp_user[:uuid], nil - # invoke setup again with a vm_uuid vm = VirtualMachine.create - response = user.setup(repo_name: 'foo/testrepo', - vm_uuid: vm.uuid) + response = user.setup(vm_uuid: vm.uuid) resp_user = find_obj_in_resp response, 'User', nil verify_user resp_user, email @@ -554,9 +500,6 @@ class UserTest < ActiveSupport::TestCase group_perm = find_obj_in_resp response, 'Link', 'arvados#group' verify_link group_perm, 'permission', 'can_write', resp_user[:uuid], groups(:all_users).uuid - repo_perm = find_obj_in_resp response, 'Link', 'arvados#repository' - verify_link repo_perm, 'permission', 'can_manage', resp_user[:uuid], nil - vm_perm = find_obj_in_resp response, 'Link', 'arvados#virtualMachine' verify_link vm_perm, 'permission', 'can_login', resp_user[:uuid], vm.uuid assert_equal("foo", vm_perm.properties["username"]) @@ -614,8 +557,6 @@ class UserTest < ActiveSupport::TestCase can_setup = (Rails.configuration.Users.AutoSetupNewUsers and (not expect_username.nil?)) - expect_repo_name = "#{expect_username}/#{expect_username}" - prior_repo = Repository.where(name: expect_repo_name).first user = User.new user.first_name = "first_name_for_newly_created_user" @@ -629,14 +570,6 @@ class UserTest < ActiveSupport::TestCase groups(:all_users).uuid, user.uuid, "permission", "can_write") - # Check for repository. - if named_repo = (prior_repo or - Repository.where(name: expect_repo_name).first) - verify_link_exists((can_setup and prior_repo.nil? and - Rails.configuration.Users.AutoSetupNewUsersWithRepository), - named_repo.uuid, user.uuid, "permission", "can_manage") - end - # Check for VM login. if (auto_vm_uuid = Rails.configuration.Users.AutoSetupNewUsersWithVmUUID) != "" verify_link_exists(can_setup, auto_vm_uuid, user.uuid, diff --git a/services/dockercleaner/arvados_version.py b/services/dockercleaner/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/services/dockercleaner/arvados_version.py +++ b/services/dockercleaner/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/services/dockercleaner/bin/arvados-docker-cleaner b/services/dockercleaner/bin/arvados-docker-cleaner index b9dcd79500..abc723fcf3 100755 --- a/services/dockercleaner/bin/arvados-docker-cleaner +++ b/services/dockercleaner/bin/arvados-docker-cleaner @@ -3,7 +3,5 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import, print_function - from arvados_docker.cleaner import main main() diff --git a/services/dockercleaner/pytest.ini b/services/dockercleaner/pytest.ini new file mode 120000 index 0000000000..05a82dbfef --- /dev/null +++ b/services/dockercleaner/pytest.ini @@ -0,0 +1 @@ +../../sdk/python/pytest.ini \ No newline at end of file diff --git a/services/dockercleaner/setup.py b/services/dockercleaner/setup.py index 9c69879b45..cb0fc8d88a 100644 --- a/services/dockercleaner/setup.py +++ b/services/dockercleaner/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import os import sys import re @@ -12,7 +11,6 @@ from setuptools import setup, find_packages import arvados_version version = arvados_version.get_version() -short_tests_only = arvados_version.short_tests_only() README = os.path.join(arvados_version.SETUP_DIR, 'README.rst') setup(name="arvados-docker-cleaner", diff --git a/services/fuse/arvados_fuse/__init__.py b/services/fuse/arvados_fuse/__init__.py index d827aefab7..c29c2430dc 100644 --- a/services/fuse/arvados_fuse/__init__.py +++ b/services/fuse/arvados_fuse/__init__.py @@ -54,11 +54,6 @@ inode assigned to it and appears in the Inodes._entries dictionary. """ -from __future__ import absolute_import -from __future__ import division -from builtins import next -from builtins import str -from builtins import object import os import llfuse import errno diff --git a/services/fuse/arvados_fuse/command.py b/services/fuse/arvados_fuse/command.py index f52121d862..8004e8303f 100644 --- a/services/fuse/arvados_fuse/command.py +++ b/services/fuse/arvados_fuse/command.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from future.utils import native_str -from builtins import range -from builtins import object import argparse import arvados import daemon @@ -410,7 +407,7 @@ class Mount(object): if self.args.replace: unmount(path=self.args.mountpoint, timeout=self.args.unmount_timeout) - llfuse.init(self.operations, native_str(self.args.mountpoint), self._fuse_options()) + llfuse.init(self.operations, str(self.args.mountpoint), self._fuse_options()) if self.daemon: daemon.DaemonContext( working_directory=os.path.dirname(self.args.mountpoint), diff --git a/services/fuse/arvados_fuse/crunchstat.py b/services/fuse/arvados_fuse/crunchstat.py index 0cb585a6ff..313c34971f 100644 --- a/services/fuse/arvados_fuse/crunchstat.py +++ b/services/fuse/arvados_fuse/crunchstat.py @@ -2,10 +2,9 @@ # # SPDX-License-Identifier: AGPL-3.0 -from builtins import str -from builtins import object import sys import time + from collections import namedtuple Stat = namedtuple("Stat", ['name', 'get']) diff --git a/services/fuse/arvados_fuse/fresh.py b/services/fuse/arvados_fuse/fresh.py index 508ee7fb73..ff548f29ee 100644 --- a/services/fuse/arvados_fuse/fresh.py +++ b/services/fuse/arvados_fuse/fresh.py @@ -2,11 +2,10 @@ # # SPDX-License-Identifier: AGPL-3.0 -from builtins import object -import time import ciso8601 import calendar import functools +import time def convertTime(t): """Parse Arvados timestamp to unix time.""" diff --git a/services/fuse/arvados_fuse/fusefile.py b/services/fuse/arvados_fuse/fusefile.py index 9279f7d99d..fce6c9b614 100644 --- a/services/fuse/arvados_fuse/fusefile.py +++ b/services/fuse/arvados_fuse/fusefile.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from builtins import bytes import json import llfuse import logging diff --git a/services/fuse/arvados_version.py b/services/fuse/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/services/fuse/arvados_version.py +++ b/services/fuse/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/services/fuse/fpm-info.sh b/services/fuse/fpm-info.sh index 4d98172f8d..8ede312d86 100644 --- a/services/fuse/fpm-info.sh +++ b/services/fuse/fpm-info.sh @@ -2,13 +2,19 @@ # # SPDX-License-Identifier: AGPL-3.0 +# We depend on the fuse package because arv-mount may run the `fusermount` tool. fpm_depends+=(fuse) case "$TARGET" in centos*|rocky*) + # We depend on libfuse for llfuse. + # We should declare a libcurl dependency, but it's a little academic + # because rpm itself depends on it, so we can be pretty sure it's installed. fpm_depends+=(fuse-libs) ;; debian* | ubuntu*) - fpm_depends+=(libcurl3-gnutls) + # We depend on libfuse2 for llfuse. + # We depend on libcurl because the Python SDK does for its Keep client. + fpm_depends+=(libfuse2 libcurl3-gnutls) ;; esac diff --git a/services/fuse/pytest.ini b/services/fuse/pytest.ini new file mode 120000 index 0000000000..05a82dbfef --- /dev/null +++ b/services/fuse/pytest.ini @@ -0,0 +1 @@ +../../sdk/python/pytest.ini \ No newline at end of file diff --git a/services/fuse/setup.py b/services/fuse/setup.py index 77dbd036d0..f9b0fcf91d 100644 --- a/services/fuse/setup.py +++ b/services/fuse/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import os import sys import re @@ -12,7 +11,6 @@ from setuptools import setup, find_packages import arvados_version version = arvados_version.get_version() -short_tests_only = arvados_version.short_tests_only() README = os.path.join(arvados_version.SETUP_DIR, 'README.rst') setup(name='arvados_fuse', @@ -34,7 +32,6 @@ setup(name='arvados_fuse', install_requires=[ *arvados_version.iter_dependencies(version), 'arvados-llfuse >= 1.5.1', - 'future', 'python-daemon', 'ciso8601 >= 2.0.0', 'setuptools', @@ -45,6 +42,6 @@ setup(name='arvados_fuse', 'Programming Language :: Python :: 3', ], test_suite='tests', - tests_require=['pbr<1.7.0', 'mock>=1.0', 'PyYAML', 'parameterized',], + tests_require=['PyYAML', 'parameterized',], zip_safe=False ) diff --git a/services/fuse/tests/fstest.py b/services/fuse/tests/fstest.py index 51e3f311ab..296f23919c 100644 --- a/services/fuse/tests/fstest.py +++ b/services/fuse/tests/fstest.py @@ -2,14 +2,11 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import print_function -from __future__ import absolute_import -from builtins import str -from builtins import range -from multiprocessing import Process import os import subprocess import sys + +from multiprocessing import Process from . import prof def fn(n): diff --git a/services/fuse/tests/integration_test.py b/services/fuse/tests/integration_test.py index e80b6983a1..24ac7baf04 100644 --- a/services/fuse/tests/integration_test.py +++ b/services/fuse/tests/integration_test.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import arvados import arvados_fuse import arvados_fuse.command @@ -12,12 +11,15 @@ import inspect import logging import multiprocessing import os -from . import run_test_server import signal import sys import tempfile import unittest +import pytest + +from . import run_test_server + @atexit.register def _pool_cleanup(): if _pool is None: @@ -91,9 +93,15 @@ class IntegrationTest(unittest.TestCase): return func(self, *args, **kwargs) finally: if self.mount and self.mount.llfuse_thread.is_alive(): - logging.warning("IntegrationTest.mount:" - " llfuse thread still alive after umount" - " -- killing test suite to avoid deadlock") - os.kill(os.getpid(), signal.SIGKILL) + # pytest uses exit status 2 when test collection failed. + # A UnitTest failing in setup/teardown counts as a + # collection failure, so pytest will exit with status 2 + # no matter what status you specify here. run-tests.sh + # looks for this status, so specify 2 just to keep + # everything as consistent as possible. + # TODO: If we refactor these tests so they're not built + # on unittest, consider using a dedicated, non-pytest + # exit code like TEMPFAIL. + pytest.exit("llfuse thread outlived test - aborting test suite to avoid deadlock", 2) return wrapper return decorator diff --git a/services/fuse/tests/mount_test_base.py b/services/fuse/tests/mount_test_base.py index 02f4009724..9768aeb74d 100644 --- a/services/fuse/tests/mount_test_base.py +++ b/services/fuse/tests/mount_test_base.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import arvados import arvados.keep import arvados_fuse as fuse @@ -11,7 +10,6 @@ import llfuse import logging import multiprocessing import os -from . import run_test_server import shutil import signal import subprocess @@ -21,10 +19,13 @@ import threading import time import unittest -logger = logging.getLogger('arvados.arv-mount') +import pytest +from . import run_test_server from .integration_test import workerPool +logger = logging.getLogger('arvados.arv-mount') + def make_block_cache(disk_cache): if disk_cache: disk_cache_dir = os.path.join(os.path.expanduser("~"), ".cache", "arvados", "keep") @@ -104,10 +105,16 @@ class MountTestBase(unittest.TestCase): t0 = time.time() self.llfuse_thread.join(timeout=60) if self.llfuse_thread.is_alive(): - logger.warning("MountTestBase.tearDown():" - " llfuse thread still alive 60s after umount" - " -- exiting with SIGKILL") - os.kill(os.getpid(), signal.SIGKILL) + # pytest uses exit status 2 when test collection failed. + # A UnitTest failing in setup/teardown counts as a + # collection failure, so pytest will exit with status 2 + # no matter what status you specify here. run-tests.sh + # looks for this status, so specify 2 just to keep + # everything as consistent as possible. + # TODO: If we refactor these tests so they're not built + # on unittest, consider using a dedicated, non-pytest + # exit code like TEMPFAIL. + pytest.exit("llfuse thread outlived test - aborting test suite to avoid deadlock", 2) waited = time.time() - t0 if waited > 0.1: logger.warning("MountTestBase.tearDown(): waited %f s for llfuse thread to end", waited) diff --git a/services/fuse/tests/performance/__init__.py b/services/fuse/tests/performance/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/services/fuse/tests/performance/performance_profiler.py b/services/fuse/tests/performance/performance_profiler.py deleted file mode 120000 index 01a6805b32..0000000000 --- a/services/fuse/tests/performance/performance_profiler.py +++ /dev/null @@ -1 +0,0 @@ -../../../../sdk/python/tests/performance/performance_profiler.py \ No newline at end of file diff --git a/services/fuse/tests/performance/test_collection_performance.py b/services/fuse/tests/performance/test_collection_performance.py deleted file mode 100644 index 98bc98abd4..0000000000 --- a/services/fuse/tests/performance/test_collection_performance.py +++ /dev/null @@ -1,491 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -from __future__ import absolute_import -from future.utils import viewitems -from builtins import str -from builtins import range -import arvados -import arvados_fuse as fuse -import llfuse -import logging -import os -import sys -import unittest -from .. import run_test_server -from ..mount_test_base import MountTestBase -from ..slow_test import slow_test - -logger = logging.getLogger('arvados.arv-mount') - -from .performance_profiler import profiled - -def fuse_createCollectionWithMultipleBlocks(mounttmp, streams=1, files_per_stream=1, data='x'): - class Test(unittest.TestCase): - def runTest(self): - self.createCollectionWithMultipleBlocks() - - @profiled - def createCollectionWithMultipleBlocks(self): - for i in range(0, streams): - os.mkdir(os.path.join(mounttmp, "./stream" + str(i))) - - # Create files - for j in range(0, files_per_stream): - with open(os.path.join(mounttmp, "./stream" + str(i), "file" + str(j) +".txt"), "w") as f: - f.write(data) - - Test().runTest() - -def fuse_readContentsFromCollectionWithMultipleBlocks(mounttmp, streams=1, files_per_stream=1, data='x'): - class Test(unittest.TestCase): - def runTest(self): - self.readContentsFromCollectionWithMultipleBlocks() - - @profiled - def readContentsFromCollectionWithMultipleBlocks(self): - for i in range(0, streams): - d1 = llfuse.listdir(os.path.join(mounttmp, 'stream'+str(i))) - for j in range(0, files_per_stream): - with open(os.path.join(mounttmp, 'stream'+str(i), 'file'+str(i)+'.txt')) as f: - self.assertEqual(data, f.read()) - - Test().runTest() - -def fuse_moveFileFromCollectionWithMultipleBlocks(mounttmp, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.moveFileFromCollectionWithMultipleBlocks() - - @profiled - def moveFileFromCollectionWithMultipleBlocks(self): - d1 = llfuse.listdir(os.path.join(mounttmp, stream)) - self.assertIn(filename, d1) - - os.rename(os.path.join(mounttmp, stream, filename), os.path.join(mounttmp, 'moved_from_'+stream+'_'+filename)) - - d1 = llfuse.listdir(os.path.join(mounttmp)) - self.assertIn('moved_from_'+stream+'_'+filename, d1) - - d1 = llfuse.listdir(os.path.join(mounttmp, stream)) - self.assertNotIn(filename, d1) - - Test().runTest() - -def fuse_deleteFileFromCollectionWithMultipleBlocks(mounttmp, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.deleteFileFromCollectionWithMultipleBlocks() - - @profiled - def deleteFileFromCollectionWithMultipleBlocks(self): - os.remove(os.path.join(mounttmp, stream, filename)) - - Test().runTest() - -# Create a collection with 2 streams, 3 files_per_stream, 2 blocks_per_file, 2**26 bytes_per_block -class CreateCollectionWithMultipleBlocksAndMoveAndDeleteFile(MountTestBase): - def setUp(self): - super(CreateCollectionWithMultipleBlocksAndMoveAndDeleteFile, self).setUp() - - @slow_test - def test_CreateCollectionWithManyBlocksAndMoveAndDeleteFile(self): - collection = arvados.collection.Collection(api_client=self.api) - collection.save_new() - - m = self.make_mount(fuse.CollectionDirectory) - with llfuse.lock: - m.new_collection(collection.api_response(), collection) - self.assertTrue(m.writable()) - - streams = 2 - files_per_stream = 3 - blocks_per_file = 2 - bytes_per_block = 2**26 - - data = 'x' * blocks_per_file * bytes_per_block - - self.pool.apply(fuse_createCollectionWithMultipleBlocks, (self.mounttmp, streams, files_per_stream, data,)) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - for i in range(0, streams): - self.assertIn('./stream' + str(i), collection2["manifest_text"]) - - for i in range(0, files_per_stream): - self.assertIn('file' + str(i) + '.txt', collection2["manifest_text"]) - - # Read file contents - self.pool.apply(fuse_readContentsFromCollectionWithMultipleBlocks, (self.mounttmp, streams, files_per_stream, data,)) - - # Move file0.txt out of the streams into . - for i in range(0, streams): - self.pool.apply(fuse_moveFileFromCollectionWithMultipleBlocks, (self.mounttmp, 'stream'+str(i), 'file0.txt',)) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - manifest_streams = collection2['manifest_text'].split('\n') - self.assertEqual(4, len(manifest_streams)) - - for i in range(0, streams): - self.assertIn('file0.txt', manifest_streams[0]) - - for i in range(0, streams): - self.assertNotIn('file0.txt', manifest_streams[i+1]) - - for i in range(0, streams): - for j in range(1, files_per_stream): - self.assertIn('file' + str(j) + '.txt', manifest_streams[i+1]) - - # Delete 'file1.txt' from all the streams - for i in range(0, streams): - self.pool.apply(fuse_deleteFileFromCollectionWithMultipleBlocks, (self.mounttmp, 'stream'+str(i), 'file1.txt')) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - manifest_streams = collection2['manifest_text'].split('\n') - self.assertEqual(4, len(manifest_streams)) - - for i in range(0, streams): - self.assertIn('file0.txt', manifest_streams[0]) - - self.assertNotIn('file1.txt', collection2['manifest_text']) - - for i in range(0, streams): - for j in range(2, files_per_stream): - self.assertIn('file' + str(j) + '.txt', manifest_streams[i+1]) - - -def fuse_createCollectionWithManyFiles(mounttmp, streams=1, files_per_stream=1, data='x'): - class Test(unittest.TestCase): - def runTest(self): - self.createCollectionWithManyFiles() - - @profiled - def createCollectionWithManyFiles(self): - for i in range(0, streams): - os.mkdir(os.path.join(mounttmp, "./stream" + str(i))) - - # Create files - for j in range(0, files_per_stream): - with open(os.path.join(mounttmp, "./stream" + str(i), "file" + str(j) +".txt"), "w") as f: - f.write(data) - - Test().runTest() - -def fuse_readContentsFromCollectionWithManyFiles(mounttmp, streams=1, files_per_stream=1, data='x'): - class Test(unittest.TestCase): - def runTest(self): - self.readContentsFromCollectionWithManyFiles() - - @profiled - def readContentsFromCollectionWithManyFiles(self): - for i in range(0, streams): - d1 = llfuse.listdir(os.path.join(mounttmp, 'stream'+str(i))) - for j in range(0, files_per_stream): - with open(os.path.join(mounttmp, 'stream'+str(i), 'file'+str(i)+'.txt')) as f: - self.assertEqual(data, f.read()) - - Test().runTest() - -def fuse_moveFileFromCollectionWithManyFiles(mounttmp, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.moveFileFromCollectionWithManyFiles() - - @profiled - def moveFileFromCollectionWithManyFiles(self): - d1 = llfuse.listdir(os.path.join(mounttmp, stream)) - self.assertIn(filename, d1) - - os.rename(os.path.join(mounttmp, stream, filename), os.path.join(mounttmp, 'moved_from_'+stream+'_'+filename)) - - d1 = llfuse.listdir(os.path.join(mounttmp)) - self.assertIn('moved_from_'+stream+'_'+filename, d1) - - d1 = llfuse.listdir(os.path.join(mounttmp, stream)) - self.assertNotIn(filename, d1) - - Test().runTest() - -def fuse_deleteFileFromCollectionWithManyFiles(mounttmp, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.deleteFileFromCollectionWithManyFiles() - - @profiled - def deleteFileFromCollectionWithManyFiles(self): - os.remove(os.path.join(mounttmp, stream, filename)) - - Test().runTest() - -# Create a collection with two streams, each with 200 files -class CreateCollectionWithManyFilesAndMoveAndDeleteFile(MountTestBase): - def setUp(self): - super(CreateCollectionWithManyFilesAndMoveAndDeleteFile, self).setUp() - - @slow_test - def test_CreateCollectionWithManyFilesAndMoveAndDeleteFile(self): - collection = arvados.collection.Collection(api_client=self.api) - collection.save_new() - - m = self.make_mount(fuse.CollectionDirectory) - with llfuse.lock: - m.new_collection(collection.api_response(), collection) - self.assertTrue(m.writable()) - - streams = 2 - files_per_stream = 200 - data = 'x' - - self.pool.apply(fuse_createCollectionWithManyFiles, (self.mounttmp, streams, files_per_stream, data,)) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - for i in range(0, streams): - self.assertIn('./stream' + str(i), collection2["manifest_text"]) - - for i in range(0, files_per_stream): - self.assertIn('file' + str(i) + '.txt', collection2["manifest_text"]) - - # Read file contents - self.pool.apply(fuse_readContentsFromCollectionWithManyFiles, (self.mounttmp, streams, files_per_stream, data,)) - - # Move file0.txt out of the streams into . - for i in range(0, streams): - self.pool.apply(fuse_moveFileFromCollectionWithManyFiles, (self.mounttmp, 'stream'+str(i), 'file0.txt',)) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - manifest_streams = collection2['manifest_text'].split('\n') - self.assertEqual(4, len(manifest_streams)) - - for i in range(0, streams): - self.assertIn('file0.txt', manifest_streams[0]) - - for i in range(0, streams): - self.assertNotIn('file0.txt', manifest_streams[i+1]) - - for i in range(0, streams): - for j in range(1, files_per_stream): - self.assertIn('file' + str(j) + '.txt', manifest_streams[i+1]) - - # Delete 'file1.txt' from all the streams - for i in range(0, streams): - self.pool.apply(fuse_deleteFileFromCollectionWithManyFiles, (self.mounttmp, 'stream'+str(i), 'file1.txt')) - - collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - - manifest_streams = collection2['manifest_text'].split('\n') - self.assertEqual(4, len(manifest_streams)) - - for i in range(0, streams): - self.assertIn('file0.txt', manifest_streams[0]) - - self.assertNotIn('file1.txt', collection2['manifest_text']) - - for i in range(0, streams): - for j in range(2, files_per_stream): - self.assertIn('file' + str(j) + '.txt', manifest_streams[i+1]) - - -def magicDirTest_MoveFileFromCollection(mounttmp, collection1, collection2, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.magicDirTest_moveFileFromCollection() - - @profiled - def magicDirTest_moveFileFromCollection(self): - os.rename(os.path.join(mounttmp, collection1, filename), os.path.join(mounttmp, collection2, filename)) - - Test().runTest() - -def magicDirTest_RemoveFileFromCollection(mounttmp, collection1, stream, filename): - class Test(unittest.TestCase): - def runTest(self): - self.magicDirTest_removeFileFromCollection() - - @profiled - def magicDirTest_removeFileFromCollection(self): - os.remove(os.path.join(mounttmp, collection1, filename)) - - Test().runTest() - -class UsingMagicDir_CreateCollectionWithManyFilesAndMoveAndDeleteFile(MountTestBase): - def setUp(self): - super(UsingMagicDir_CreateCollectionWithManyFilesAndMoveAndDeleteFile, self).setUp() - - @profiled - def magicDirTest_createCollectionWithManyFiles(self, streams=0, files_per_stream=0, data='x'): - # Create collection - collection = arvados.collection.Collection(api_client=self.api) - for j in range(0, files_per_stream): - with collection.open("file"+str(j)+".txt", "w") as f: - f.write(data) - collection.save_new() - return collection - - @profiled - def magicDirTest_readCollectionContents(self, collection, streams=1, files_per_stream=1, data='x'): - mount_ls = os.listdir(os.path.join(self.mounttmp, collection)) - - files = {} - for j in range(0, files_per_stream): - files[os.path.join(self.mounttmp, collection, 'file'+str(j)+'.txt')] = data - - for k, v in viewItems(files): - with open(os.path.join(self.mounttmp, collection, k)) as f: - self.assertEqual(v, f.read()) - - @slow_test - def test_UsingMagicDirCreateCollectionWithManyFilesAndMoveAndDeleteFile(self): - streams = 2 - files_per_stream = 200 - data = 'x' - - collection1 = self.magicDirTest_createCollectionWithManyFiles() - # Create collection with multiple files - collection2 = self.magicDirTest_createCollectionWithManyFiles(streams, files_per_stream, data) - - # Mount FuseMagicDir - self.make_mount(fuse.MagicDirectory) - - self.magicDirTest_readCollectionContents(collection2.manifest_locator(), streams, files_per_stream, data) - - # Move file0.txt out of the collection2 into collection1 - self.pool.apply(magicDirTest_MoveFileFromCollection, (self.mounttmp, collection2.manifest_locator(), - collection1.manifest_locator(), 'stream0', 'file0.txt',)) - updated_collection = self.api.collections().get(uuid=collection2.manifest_locator()).execute() - self.assertFalse('file0.txt' in updated_collection['manifest_text']) - self.assertTrue('file1.txt' in updated_collection['manifest_text']) - - # Delete file1.txt from collection2 - self.pool.apply(magicDirTest_RemoveFileFromCollection, (self.mounttmp, collection2.manifest_locator(), 'stream0', 'file1.txt',)) - updated_collection = self.api.collections().get(uuid=collection2.manifest_locator()).execute() - self.assertFalse('file1.txt' in updated_collection['manifest_text']) - self.assertTrue('file2.txt' in updated_collection['manifest_text']) - - -def magicDirTest_MoveAllFilesFromCollection(mounttmp, from_collection, to_collection, stream, files_per_stream): - class Test(unittest.TestCase): - def runTest(self): - self.magicDirTest_moveAllFilesFromCollection() - - @profiled - def magicDirTest_moveAllFilesFromCollection(self): - for j in range(0, files_per_stream): - os.rename(os.path.join(mounttmp, from_collection, 'file'+str(j)+'.txt'), os.path.join(mounttmp, to_collection, 'file'+str(j)+'.txt')) - - Test().runTest() - -class UsingMagicDir_CreateCollectionWithManyFilesAndMoveAllFilesIntoAnother(MountTestBase): - def setUp(self): - super(UsingMagicDir_CreateCollectionWithManyFilesAndMoveAllFilesIntoAnother, self).setUp() - - @profiled - def magicDirTestMoveAllFiles_createCollectionWithManyFiles(self, streams=0, files_per_stream=0, - blocks_per_file=0, bytes_per_block=0, data='x'): - # Create collection - collection = arvados.collection.Collection(api_client=self.api) - for j in range(0, files_per_stream): - with collection.open("file"+str(j)+".txt", "w") as f: - f.write(data) - collection.save_new() - return collection - - @slow_test - def test_UsingMagicDirCreateCollectionWithManyFilesAndMoveAllFilesIntoAnother(self): - streams = 2 - files_per_stream = 200 - data = 'x' - - collection1 = self.magicDirTestMoveAllFiles_createCollectionWithManyFiles() - # Create collection with multiple files - collection2 = self.magicDirTestMoveAllFiles_createCollectionWithManyFiles(streams, files_per_stream, data) - - # Mount FuseMagicDir - self.make_mount(fuse.MagicDirectory) - - # Move all files from collection2 into collection1 - self.pool.apply(magicDirTest_MoveAllFilesFromCollection, (self.mounttmp, collection2.manifest_locator(), - collection1.manifest_locator(), 'stream0', files_per_stream,)) - - updated_collection = self.api.collections().get(uuid=collection2.manifest_locator()).execute() - file_names = ["file%i.txt" % i for i in range(0, files_per_stream)] - for name in file_names: - self.assertFalse(name in updated_collection['manifest_text']) - - updated_collection = self.api.collections().get(uuid=collection1.manifest_locator()).execute() - for name in file_names: - self.assertTrue(name in updated_collection['manifest_text']) - - -# Move one file at a time from one collection into another -class UsingMagicDir_CreateCollectionWithManyFilesAndMoveEachFileIntoAnother(MountTestBase): - def setUp(self): - super(UsingMagicDir_CreateCollectionWithManyFilesAndMoveEachFileIntoAnother, self).setUp() - - @profiled - def magicDirTestMoveFiles_createCollectionWithManyFiles(self, streams=0, files_per_stream=0, data='x'): - # Create collection - collection = arvados.collection.Collection(api_client=self.api) - for j in range(0, files_per_stream): - with collection.open("file"+str(j)+".txt", "w") as f: - f.write(data) - collection.save_new() - return collection - - def magicDirTestMoveFiles_oneEachIntoAnother(self, from_collection, to_collection, files_per_stream): - for j in range(0, files_per_stream): - self.pool.apply(magicDirTest_MoveFileFromCollection, (self.mounttmp, from_collection.manifest_locator(), - to_collection.manifest_locator(), 'stream0', 'file'+str(j)+'.txt',)) - - @slow_test - def test_UsingMagicDirCreateCollectionWithManyFilesAndMoveEachFileIntoAnother(self): - streams = 2 - files_per_stream = 200 - data = 'x' - - collection1 = self.magicDirTestMoveFiles_createCollectionWithManyFiles() - # Create collection with multiple files - collection2 = self.magicDirTestMoveFiles_createCollectionWithManyFiles(streams, files_per_stream, data) - - # Mount FuseMagicDir - self.make_mount(fuse.MagicDirectory) - - # Move all files from collection2 into collection1 - self.magicDirTestMoveFiles_oneEachIntoAnother(collection2, collection1, files_per_stream) - - updated_collection = self.api.collections().get(uuid=collection2.manifest_locator()).execute() - file_names = ["file%i.txt" % i for i in range(0, files_per_stream)] - for name in file_names: - self.assertFalse(name in updated_collection['manifest_text']) - - updated_collection = self.api.collections().get(uuid=collection1.manifest_locator()).execute() - for name in file_names: - self.assertTrue(name in updated_collection['manifest_text']) - -class FuseListLargeProjectContents(MountTestBase): - @profiled - def getProjectWithManyCollections(self): - project_contents = llfuse.listdir(self.mounttmp) - self.assertEqual(201, len(project_contents)) - self.assertIn('Collection_1', project_contents) - - @profiled - def listContentsInProjectWithManyCollections(self): - project_contents = llfuse.listdir(self.mounttmp) - self.assertEqual(201, len(project_contents)) - self.assertIn('Collection_1', project_contents) - - for collection_name in project_contents: - collection_contents = llfuse.listdir(os.path.join(self.mounttmp, collection_name)) - self.assertIn('baz', collection_contents) - - @slow_test - def test_listLargeProjectContents(self): - self.make_mount(fuse.ProjectDirectory, - project_object=run_test_server.fixture('groups')['project_with_201_collections']) - self.getProjectWithManyCollections() - self.listContentsInProjectWithManyCollections() diff --git a/services/fuse/tests/prof.py b/services/fuse/tests/prof.py index f9ce1881de..5bdb1b2e7b 100644 --- a/services/fuse/tests/prof.py +++ b/services/fuse/tests/prof.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import print_function -from builtins import object import time class CountTime(object): diff --git a/services/fuse/tests/slow_test.py b/services/fuse/tests/slow_test.py deleted file mode 120000 index c7e1f7fada..0000000000 --- a/services/fuse/tests/slow_test.py +++ /dev/null @@ -1 +0,0 @@ -../../../sdk/python/tests/slow_test.py \ No newline at end of file diff --git a/services/fuse/tests/test_cache.py b/services/fuse/tests/test_cache.py index 46ed0be411..3f6b804b92 100644 --- a/services/fuse/tests/test_cache.py +++ b/services/fuse/tests/test_cache.py @@ -2,7 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from builtins import range import arvados import arvados.collection import arvados_fuse diff --git a/services/fuse/tests/test_command_args.py b/services/fuse/tests/test_command_args.py index b08ab19335..a6a387789d 100644 --- a/services/fuse/tests/test_command_args.py +++ b/services/fuse/tests/test_command_args.py @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from __future__ import print_function -from six import assertRegex import arvados import arvados_fuse import arvados_fuse.command @@ -14,14 +11,16 @@ import io import json import llfuse import logging -import mock import os -from . import run_test_server import sys import tempfile import unittest import resource +from unittest import mock + +from . import run_test_server + def noexit(func): """If argparse or arvados_fuse tries to exit, fail the test instead""" class SystemExitCaught(Exception): @@ -84,13 +83,13 @@ class MountArgsTest(unittest.TestCase): e = self.check_ent_type(arvados_fuse.StringFile, 'README') readme = e.readfrom(0, -1).decode() - assertRegex(self, readme, r'active-user@arvados\.local') - assertRegex(self, readme, r'\n$') + self.assertRegex(readme, r'active-user@arvados\.local') + self.assertRegex(readme, r'\n$') e = self.check_ent_type(arvados_fuse.StringFile, 'by_id', 'README') txt = e.readfrom(0, -1).decode() - assertRegex(self, txt, r'portable data hash') - assertRegex(self, txt, r'\n$') + self.assertRegex(txt, r'portable data hash') + self.assertRegex(txt, r'\n$') @noexit def test_by_id(self): @@ -199,7 +198,7 @@ class MountArgsTest(unittest.TestCase): with self.assertRaises(SystemExit): args = arvados_fuse.command.ArgumentParser().parse_args(['--version']) - assertRegex(self, sys.stdout.getvalue(), "[0-9]+\.[0-9]+\.[0-9]+") + self.assertRegex(sys.stdout.getvalue(), "[0-9]+\.[0-9]+\.[0-9]+") sys.stderr.close() sys.stderr = origerr sys.stdout = origout diff --git a/services/fuse/tests/test_crunchstat.py b/services/fuse/tests/test_crunchstat.py index 3cf15fe113..32272a83c4 100644 --- a/services/fuse/tests/test_crunchstat.py +++ b/services/fuse/tests/test_crunchstat.py @@ -2,12 +2,10 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import subprocess from .integration_test import IntegrationTest - class CrunchstatTest(IntegrationTest): def test_crunchstat(self): output = subprocess.check_output( diff --git a/services/fuse/tests/test_exec.py b/services/fuse/tests/test_exec.py index f977990026..c67cc55f34 100644 --- a/services/fuse/tests/test_exec.py +++ b/services/fuse/tests/test_exec.py @@ -2,17 +2,15 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from six import assertRegex import arvados_fuse.command import json import multiprocessing import os -from . import run_test_server import shlex import tempfile import unittest +from . import run_test_server from .integration_test import workerPool def try_exec(mnt, cmd): @@ -58,7 +56,4 @@ class ExecMode(unittest.TestCase): shlex.quote(os.path.join(self.okfile)), )])) with open(self.okfile) as f: - assertRegex( - self, - json.load(f)['manifest_text'], - r' 0:3:foo.txt\n') + self.assertRegex(json.load(f)['manifest_text'], r' 0:3:foo.txt\n') diff --git a/services/fuse/tests/test_inodes.py b/services/fuse/tests/test_inodes.py index c5c92a9b3f..cc22f521e0 100644 --- a/services/fuse/tests/test_inodes.py +++ b/services/fuse/tests/test_inodes.py @@ -3,11 +3,12 @@ # SPDX-License-Identifier: AGPL-3.0 import arvados_fuse -import mock import unittest import llfuse import logging +from unittest import mock + class InodeTests(unittest.TestCase): # The following tests call next(inodes._counter) because inode 1 diff --git a/services/fuse/tests/test_mount.py b/services/fuse/tests/test_mount.py index b3bec39cc5..f5f61baeb3 100644 --- a/services/fuse/tests/test_mount.py +++ b/services/fuse/tests/test_mount.py @@ -2,36 +2,32 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from future.utils import viewitems -from builtins import str -from builtins import object -from pathlib import Path -from six import assertRegex import errno import json import llfuse import logging -import mock import os import subprocess import time import unittest import tempfile -import parameterized + +from pathlib import Path +from unittest import mock import arvados import arvados_fuse as fuse +import parameterized + from arvados_fuse import fusedir -from . import run_test_server +from . import run_test_server from .integration_test import IntegrationTest from .mount_test_base import MountTestBase from .test_tmp_collection import storage_classes_desired logger = logging.getLogger('arvados.arv-mount') - class AssertWithTimeout(object): """Allow some time for an assertion to pass.""" @@ -124,7 +120,7 @@ class FuseMountTest(MountTestBase): 'dir2/dir3/thing7.txt': 'data 7', 'dir2/dir3/thing8.txt': 'data 8'} - for k, v in viewitems(files): + for k, v in files.items(): with open(os.path.join(self.mounttmp, k), 'rb') as f: self.assertEqual(v, f.read().decode()) @@ -189,7 +185,7 @@ class FuseMagicTest(MountTestBase): files = {} files[os.path.join(self.mounttmp, self.testcollection, 'thing1.txt')] = 'data 1' - for k, v in viewitems(files): + for k, v in files.items(): with open(os.path.join(self.mounttmp, k), 'rb') as f: self.assertEqual(v, f.read().decode()) @@ -312,7 +308,7 @@ class FuseHomeTest(MountTestBase): 'anonymously_accessible_project'] found_in = 0 found_not_in = 0 - for name, item in viewitems(run_test_server.fixture('collections')): + for name, item in run_test_server.fixture('collections').items(): if 'name' not in item: pass elif item['owner_uuid'] == public_project['uuid']: @@ -451,7 +447,7 @@ class FuseCreateFileTest(MountTestBase): self.assertEqual(["file1.txt"], d1) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\. d41d8cd98f00b204e9800998ecf8427e\+0\+A\S+ 0:0:file1\.txt$') @@ -494,7 +490,7 @@ class FuseWriteFileTest(MountTestBase): self.assertEqual(12, self.operations.read_counter.get()) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') @@ -533,7 +529,7 @@ class FuseUpdateFileTest(MountTestBase): self.pool.apply(fuseUpdateFileTestHelper, (self.mounttmp,)) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\. daaef200ebb921e011e3ae922dd3266b\+11\+A\S+ 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:11:file1\.txt 22:1:file1\.txt$') @@ -573,7 +569,7 @@ class FuseMkdirTest(MountTestBase): self.pool.apply(fuseMkdirTestHelper, (self.mounttmp,)) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') @@ -640,13 +636,13 @@ class FuseRmTest(MountTestBase): # Starting manifest collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') self.pool.apply(fuseRmTestHelperDeleteFile, (self.mounttmp,)) # Empty directories are represented by an empty file named "." collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'./testdir d41d8cd98f00b204e9800998ecf8427e\+0\+A\S+ 0:0:\\056\n') self.pool.apply(fuseRmTestHelperRmdir, (self.mounttmp,)) @@ -697,13 +693,13 @@ class FuseMvFileTest(MountTestBase): # Starting manifest collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') self.pool.apply(fuseMvFileTestHelperMoveFile, (self.mounttmp,)) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt\n\./testdir d41d8cd98f00b204e9800998ecf8427e\+0\+A\S+ 0:0:\\056\n') @@ -731,7 +727,7 @@ class FuseRenameTest(MountTestBase): # Starting manifest collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') d1 = llfuse.listdir(os.path.join(self.mounttmp)) @@ -747,7 +743,7 @@ class FuseRenameTest(MountTestBase): self.assertEqual(["file1.txt"], d1) collection2 = self.api.collections().get(uuid=collection.manifest_locator()).execute() - assertRegex(self, collection2["manifest_text"], + self.assertRegex(collection2["manifest_text"], r'\./testdir2 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$') @@ -818,7 +814,7 @@ def fuseFileConflictTestHelper(mounttmp, uuid, keeptmp, settings): with open(os.path.join(mounttmp, "file1.txt"), "r") as f: self.assertEqual(f.read(), "bar") - assertRegex(self, d1[1], + self.assertRegex(d1[1], r'file1\.txt~\d\d\d\d\d\d\d\d-\d\d\d\d\d\d~conflict~') with open(os.path.join(mounttmp, d1[1]), "r") as f: @@ -923,7 +919,7 @@ class FuseMvFileBetweenCollectionsTest(MountTestBase): collection1.update() collection2.update() - assertRegex(self, collection1.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") + self.assertRegex(collection1.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") self.assertEqual(collection2.manifest_text(), "") self.pool.apply(fuseMvFileBetweenCollectionsTest2, (self.mounttmp, @@ -934,7 +930,7 @@ class FuseMvFileBetweenCollectionsTest(MountTestBase): collection2.update() self.assertEqual(collection1.manifest_text(), "") - assertRegex(self, collection2.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file2\.txt$") + self.assertRegex(collection2.manifest_text(), r"\. 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file2\.txt$") collection1.stop_threads() collection2.stop_threads() @@ -994,7 +990,7 @@ class FuseMvDirBetweenCollectionsTest(MountTestBase): collection1.update() collection2.update() - assertRegex(self, collection1.manifest_text(), r"\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") + self.assertRegex(collection1.manifest_text(), r"\./testdir 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") self.assertEqual(collection2.manifest_text(), "") self.pool.apply(fuseMvDirBetweenCollectionsTest2, (self.mounttmp, @@ -1005,7 +1001,7 @@ class FuseMvDirBetweenCollectionsTest(MountTestBase): collection2.update() self.assertEqual(collection1.manifest_text(), "") - assertRegex(self, collection2.manifest_text(), r"\./testdir2 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") + self.assertRegex(collection2.manifest_text(), r"\./testdir2 86fb269d190d2c85f6e0468ceca42a20\+12\+A\S+ 0:12:file1\.txt$") collection1.stop_threads() collection2.stop_threads() @@ -1200,7 +1196,7 @@ class FuseMagicTestPDHOnly(MountTestBase): files = {} files[os.path.join(self.mounttmp, self.testcollection, 'thing1.txt')] = 'data 1' - for k, v in viewitems(files): + for k, v in files.items(): with open(os.path.join(self.mounttmp, k), 'rb') as f: self.assertEqual(v, f.read().decode()) diff --git a/services/fuse/tests/test_retry.py b/services/fuse/tests/test_retry.py index 44ab5cce91..5bc8a0bd45 100644 --- a/services/fuse/tests/test_retry.py +++ b/services/fuse/tests/test_retry.py @@ -2,22 +2,19 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from future import standard_library -standard_library.install_aliases() import arvados import arvados_fuse.command import json -import mock import os import pycurl import queue -from . import run_test_server import tempfile import unittest -from .integration_test import IntegrationTest +from unittest import mock +from . import run_test_server +from .integration_test import IntegrationTest class KeepClientRetry(unittest.TestCase): origKeepClient = arvados.keep.KeepClient diff --git a/services/fuse/tests/test_tmp_collection.py b/services/fuse/tests/test_tmp_collection.py index c59024267a..7ab6d52243 100644 --- a/services/fuse/tests/test_tmp_collection.py +++ b/services/fuse/tests/test_tmp_collection.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from builtins import range -from six import assertRegex import arvados import arvados_fuse import arvados_fuse.command @@ -18,7 +16,6 @@ from .mount_test_base import MountTestBase logger = logging.getLogger('arvados.arv-mount') - class TmpCollectionArgsTest(unittest.TestCase): def setUp(self): self.tmpdir = tempfile.mkdtemp() @@ -107,8 +104,7 @@ class TmpCollectionTest(IntegrationTest): def _test_tmp_onefile(self, tmpdir): with open(os.path.join(tmpdir, 'foo'), 'w') as f: f.write('foo') - assertRegex( - self, + self.assertRegex( current_manifest(tmpdir), r'^\. acbd18db4cc2f85cedef654fccc4a4d8\+3(\+\S+)? 0:3:foo\n$') @@ -137,7 +133,7 @@ class TmpCollectionTest(IntegrationTest): else: with open(path, 'w') as f: f.write(content) - assertRegex(self, current_manifest(tmpdir), expect) + self.assertRegex(current_manifest(tmpdir), expect) @IntegrationTest.mount(argv=mnt_args) def test_tmp_rewrite(self): @@ -150,4 +146,4 @@ class TmpCollectionTest(IntegrationTest): f.write("b2") with open(os.path.join(tmpdir, "b1"), 'w') as f: f.write("1b") - assertRegex(self, current_manifest(tmpdir), "^\. ed4f3f67c70b02b29c50ce1ea26666bd\+4(\+\S+)? 0:2:b1 2:2:b2\n$") + self.assertRegex(current_manifest(tmpdir), "^\. ed4f3f67c70b02b29c50ce1ea26666bd\+4(\+\S+)? 0:2:b1 2:2:b2\n$") diff --git a/services/fuse/tests/test_token_expiry.py b/services/fuse/tests/test_token_expiry.py index 040db2e096..89076d72cb 100644 --- a/services/fuse/tests/test_token_expiry.py +++ b/services/fuse/tests/test_token_expiry.py @@ -2,12 +2,10 @@ # # SPDX-License-Identifier: AGPL-3.0 -from builtins import range import apiclient import arvados import arvados_fuse import logging -import mock import multiprocessing import os import re @@ -15,6 +13,8 @@ import sys import time import unittest +from unittest import mock + from .integration_test import IntegrationTest logger = logging.getLogger('arvados.arv-mount') @@ -65,8 +65,8 @@ class TokenExpiryTest(IntegrationTest): @staticmethod def _test_refresh_old_manifest(self, zzz): - uuid = 'zzzzz-4zz18-op4e2lbej01tcvu' - fnm = 'zzzzz-8i9sb-0vsrcqi7whchuil.log.txt' + uuid = 'zzzzz-4zz18-logcollection02' + fnm = 'crunch-run.txt' os.listdir(os.path.join(zzz, uuid)) for _ in range(8): with open(os.path.join(zzz, uuid, fnm)) as f: diff --git a/services/fuse/tests/test_unmount.py b/services/fuse/tests/test_unmount.py index 6a19b33454..3949fd5de4 100644 --- a/services/fuse/tests/test_unmount.py +++ b/services/fuse/tests/test_unmount.py @@ -2,8 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import -from builtins import bytes import arvados_fuse.unmount import os import subprocess diff --git a/services/githttpd/auth_handler.go b/services/githttpd/auth_handler.go deleted file mode 100644 index c6b23fd4c8..0000000000 --- a/services/githttpd/auth_handler.go +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "errors" - "log" - "net/http" - "os" - "regexp" - "strings" - "time" - - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadosclient" - "git.arvados.org/arvados.git/sdk/go/auth" - "git.arvados.org/arvados.git/sdk/go/httpserver" - "github.com/sirupsen/logrus" -) - -type authHandler struct { - handler http.Handler - clientPool *arvadosclient.ClientPool - cluster *arvados.Cluster -} - -func (h *authHandler) CheckHealth() error { - return nil -} - -func (h *authHandler) Done() <-chan struct{} { - return nil -} - -func (h *authHandler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { - var statusCode int - var statusText string - var apiToken string - - w := httpserver.WrapResponseWriter(wOrig) - - if r.Method == "OPTIONS" { - method := r.Header.Get("Access-Control-Request-Method") - if method != "GET" && method != "POST" { - w.WriteHeader(http.StatusMethodNotAllowed) - return - } - w.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Type") - w.Header().Set("Access-Control-Allow-Methods", "GET, POST") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Max-Age", "86400") - w.WriteHeader(http.StatusOK) - return - } - - if r.Header.Get("Origin") != "" { - // Allow simple cross-origin requests without user - // credentials ("user credentials" as defined by CORS, - // i.e., cookies, HTTP authentication, and client-side - // SSL certificates. See - // http://www.w3.org/TR/cors/#user-credentials). - w.Header().Set("Access-Control-Allow-Origin", "*") - } - - defer func() { - if w.WroteStatus() == 0 { - // Nobody has called WriteHeader yet: that - // must be our job. - w.WriteHeader(statusCode) - if statusCode >= 400 { - w.Write([]byte(statusText)) - } - } - }() - - creds := auth.CredentialsFromRequest(r) - if len(creds.Tokens) == 0 { - statusCode, statusText = http.StatusUnauthorized, "no credentials provided" - w.Header().Add("WWW-Authenticate", "Basic realm=\"git\"") - return - } - apiToken = creds.Tokens[0] - - // Access to paths "/foo/bar.git/*" and "/foo/bar/.git/*" are - // protected by the permissions on the repository named - // "foo/bar". - pathParts := strings.SplitN(r.URL.Path[1:], ".git/", 2) - if len(pathParts) != 2 { - statusCode, statusText = http.StatusNotFound, "not found" - return - } - repoName := pathParts[0] - repoName = strings.TrimRight(repoName, "/") - httpserver.SetResponseLogFields(r.Context(), logrus.Fields{ - "repoName": repoName, - }) - - arv := h.clientPool.Get() - if arv == nil { - statusCode, statusText = http.StatusInternalServerError, "connection pool failed: "+h.clientPool.Err().Error() - return - } - defer h.clientPool.Put(arv) - - // Log the UUID if the supplied token is a v2 token, otherwise - // just the last five characters. - httpserver.SetResponseLogFields(r.Context(), logrus.Fields{ - "tokenUUID": func() string { - if strings.HasPrefix(apiToken, "v2/") && strings.IndexRune(apiToken[3:], '/') == 27 { - // UUID part of v2 token - return apiToken[3:30] - } else if len(apiToken) > 5 { - return "[...]" + apiToken[len(apiToken)-5:] - } else { - return apiToken - } - }(), - }) - - // Ask API server whether the repository is readable using - // this token (by trying to read it!) - arv.ApiToken = apiToken - repoUUID, err := h.lookupRepo(arv, repoName) - if err != nil { - statusCode, statusText = http.StatusInternalServerError, err.Error() - return - } - if repoUUID == "" { - statusCode, statusText = http.StatusNotFound, "not found" - return - } - - isWrite := strings.HasSuffix(r.URL.Path, "/git-receive-pack") - if !isWrite { - statusText = "read" - } else { - err := arv.Update("repositories", repoUUID, arvadosclient.Dict{ - "repository": arvadosclient.Dict{ - "modified_at": time.Now().String(), - }, - }, &arvadosclient.Dict{}) - if err != nil { - statusCode, statusText = http.StatusForbidden, err.Error() - return - } - statusText = "write" - } - - // Regardless of whether the client asked for "/foo.git" or - // "/foo/.git", we choose whichever variant exists in our repo - // root, and we try {uuid}.git and {uuid}/.git first. If none - // of these exist, we 404 even though the API told us the repo - // _should_ exist (presumably this means the repo was just - // created, and gitolite sync hasn't run yet). - rewrittenPath := "" - tryDirs := []string{ - "/" + repoUUID + ".git", - "/" + repoUUID + "/.git", - "/" + repoName + ".git", - "/" + repoName + "/.git", - } - for _, dir := range tryDirs { - if fileInfo, err := os.Stat(h.cluster.Git.Repositories + dir); err != nil { - if !os.IsNotExist(err) { - statusCode, statusText = http.StatusInternalServerError, err.Error() - return - } - } else if fileInfo.IsDir() { - rewrittenPath = dir + "/" + pathParts[1] - break - } - } - if rewrittenPath == "" { - log.Println("WARNING:", repoUUID, - "git directory not found in", h.cluster.Git.Repositories, tryDirs) - // We say "content not found" to disambiguate from the - // earlier "API says that repo does not exist" error. - statusCode, statusText = http.StatusNotFound, "content not found" - return - } - r.URL.Path = rewrittenPath - - h.handler.ServeHTTP(w, r) -} - -var uuidRegexp = regexp.MustCompile(`^[0-9a-z]{5}-s0uqq-[0-9a-z]{15}$`) - -func (h *authHandler) lookupRepo(arv *arvadosclient.ArvadosClient, repoName string) (string, error) { - reposFound := arvadosclient.Dict{} - var column string - if uuidRegexp.MatchString(repoName) { - column = "uuid" - } else { - column = "name" - } - err := arv.List("repositories", arvadosclient.Dict{ - "filters": [][]string{{column, "=", repoName}}, - }, &reposFound) - if err != nil { - return "", err - } else if avail, ok := reposFound["items_available"].(float64); !ok { - return "", errors.New("bad list response from API") - } else if avail < 1 { - return "", nil - } else if avail > 1 { - return "", errors.New("name collision") - } - return reposFound["items"].([]interface{})[0].(map[string]interface{})["uuid"].(string), nil -} diff --git a/services/githttpd/auth_handler_test.go b/services/githttpd/auth_handler_test.go deleted file mode 100644 index 2d1ec966a4..0000000000 --- a/services/githttpd/auth_handler_test.go +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "io" - "log" - "net/http" - "net/http/httptest" - "net/url" - "path/filepath" - "strings" - - "git.arvados.org/arvados.git/lib/config" - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadosclient" - "git.arvados.org/arvados.git/sdk/go/arvadostest" - "git.arvados.org/arvados.git/sdk/go/ctxlog" - check "gopkg.in/check.v1" -) - -var _ = check.Suite(&AuthHandlerSuite{}) - -type AuthHandlerSuite struct { - cluster *arvados.Cluster -} - -func (s *AuthHandlerSuite) SetUpTest(c *check.C) { - arvadostest.ResetEnv() - repoRoot, err := filepath.Abs("../api/tmp/git/test") - c.Assert(err, check.IsNil) - - cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load() - c.Assert(err, check.Equals, nil) - s.cluster, err = cfg.GetCluster("") - c.Assert(err, check.Equals, nil) - - s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{{Host: "localhost:0"}: {}} - s.cluster.TLS.Insecure = true - s.cluster.Git.GitCommand = "/usr/bin/git" - s.cluster.Git.Repositories = repoRoot -} - -func (s *AuthHandlerSuite) TestPermission(c *check.C) { - client, err := arvados.NewClientFromConfig(s.cluster) - c.Assert(err, check.IsNil) - ac, err := arvadosclient.New(client) - c.Assert(err, check.IsNil) - h := &authHandler{ - cluster: s.cluster, - clientPool: &arvadosclient.ClientPool{Prototype: ac}, - handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - log.Printf("%v", r.URL) - io.WriteString(w, r.URL.Path) - }), - } - baseURL, err := url.Parse("http://git.example/") - c.Assert(err, check.IsNil) - for _, trial := range []struct { - label string - token string - pathIn string - pathOut string - status int - }{ - { - label: "read repo by name", - token: arvadostest.ActiveToken, - pathIn: arvadostest.Repository2Name + ".git/git-upload-pack", - pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack", - }, - { - label: "read repo by uuid", - token: arvadostest.ActiveToken, - pathIn: arvadostest.Repository2UUID + ".git/git-upload-pack", - pathOut: arvadostest.Repository2UUID + ".git/git-upload-pack", - }, - { - label: "write repo by name", - token: arvadostest.ActiveToken, - pathIn: arvadostest.Repository2Name + ".git/git-receive-pack", - pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack", - }, - { - label: "write repo by uuid", - token: arvadostest.ActiveToken, - pathIn: arvadostest.Repository2UUID + ".git/git-receive-pack", - pathOut: arvadostest.Repository2UUID + ".git/git-receive-pack", - }, - { - label: "uuid not found", - token: arvadostest.ActiveToken, - pathIn: strings.Replace(arvadostest.Repository2UUID, "6", "z", -1) + ".git/git-upload-pack", - status: http.StatusNotFound, - }, - { - label: "name not found", - token: arvadostest.ActiveToken, - pathIn: "nonexistent-bogus.git/git-upload-pack", - status: http.StatusNotFound, - }, - { - label: "read read-only repo", - token: arvadostest.SpectatorToken, - pathIn: arvadostest.FooRepoName + ".git/git-upload-pack", - pathOut: arvadostest.FooRepoUUID + "/.git/git-upload-pack", - }, - { - label: "write read-only repo", - token: arvadostest.SpectatorToken, - pathIn: arvadostest.FooRepoName + ".git/git-receive-pack", - status: http.StatusForbidden, - }, - } { - c.Logf("trial label: %q", trial.label) - u, err := baseURL.Parse(trial.pathIn) - c.Assert(err, check.IsNil) - resp := httptest.NewRecorder() - req := &http.Request{ - Method: "POST", - URL: u, - Header: http.Header{ - "Authorization": {"Bearer " + trial.token}}} - h.ServeHTTP(resp, req) - if trial.status == 0 { - trial.status = http.StatusOK - } - c.Check(resp.Code, check.Equals, trial.status) - if trial.status < 400 { - if trial.pathOut != "" && !strings.HasPrefix(trial.pathOut, "/") { - trial.pathOut = "/" + trial.pathOut - } - c.Check(resp.Body.String(), check.Equals, trial.pathOut) - } - } -} - -func (s *AuthHandlerSuite) TestCORS(c *check.C) { - h := &authHandler{cluster: s.cluster} - - // CORS preflight - resp := httptest.NewRecorder() - req := &http.Request{ - Method: "OPTIONS", - Header: http.Header{ - "Origin": {"*"}, - "Access-Control-Request-Method": {"GET"}, - }, - } - h.ServeHTTP(resp, req) - c.Check(resp.Code, check.Equals, http.StatusOK) - c.Check(resp.Header().Get("Access-Control-Allow-Methods"), check.Equals, "GET, POST") - c.Check(resp.Header().Get("Access-Control-Allow-Headers"), check.Equals, "Authorization, Content-Type") - c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*") - c.Check(resp.Body.String(), check.Equals, "") - - // CORS actual request. Bogus token and path ensure - // authHandler responds 4xx without calling our wrapped (nil) - // handler. - u, err := url.Parse("git.zzzzz.arvadosapi.com/test") - c.Assert(err, check.Equals, nil) - resp = httptest.NewRecorder() - req = &http.Request{ - Method: "GET", - URL: u, - Header: http.Header{ - "Origin": {"*"}, - "Authorization": {"OAuth2 foobar"}, - }, - } - h.ServeHTTP(resp, req) - c.Check(resp.Header().Get("Access-Control-Allow-Origin"), check.Equals, "*") -} diff --git a/services/githttpd/cmd.go b/services/githttpd/cmd.go deleted file mode 100644 index e6ca3c0743..0000000000 --- a/services/githttpd/cmd.go +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "context" - - "git.arvados.org/arvados.git/lib/service" - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadosclient" - "github.com/prometheus/client_golang/prometheus" -) - -var Command = service.Command(arvados.ServiceNameGitHTTP, newHandler) - -func newHandler(ctx context.Context, cluster *arvados.Cluster, token string, reg *prometheus.Registry) service.Handler { - client, err := arvados.NewClientFromConfig(cluster) - if err != nil { - return service.ErrorHandler(ctx, cluster, err) - } - ac, err := arvadosclient.New(client) - if err != nil { - return service.ErrorHandler(ctx, cluster, err) - } - return &authHandler{ - clientPool: &arvadosclient.ClientPool{Prototype: ac}, - cluster: cluster, - handler: newGitHandler(ctx, cluster), - } -} diff --git a/services/githttpd/git_handler.go b/services/githttpd/git_handler.go deleted file mode 100644 index 7c94294c04..0000000000 --- a/services/githttpd/git_handler.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "context" - "net" - "net/http" - "net/http/cgi" - "os" - - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/ctxlog" -) - -// gitHandler is an http.Handler that invokes git-http-backend (or -// whatever backend is configured) via CGI, with appropriate -// environment variables in place for git-http-backend or -// gitolite-shell. -type gitHandler struct { - cgi.Handler -} - -func newGitHandler(ctx context.Context, cluster *arvados.Cluster) http.Handler { - const glBypass = "GL_BYPASS_ACCESS_CHECKS" - const glHome = "GITOLITE_HTTP_HOME" - var env []string - path := os.Getenv("PATH") - if cluster.Git.GitoliteHome != "" { - env = append(env, - glHome+"="+cluster.Git.GitoliteHome, - glBypass+"=1") - path = path + ":" + cluster.Git.GitoliteHome + "/bin" - } else if home, bypass := os.Getenv(glHome), os.Getenv(glBypass); home != "" || bypass != "" { - env = append(env, glHome+"="+home, glBypass+"="+bypass) - ctxlog.FromContext(ctx).Printf("DEPRECATED: Passing through %s and %s environment variables. Use GitoliteHome configuration instead.", glHome, glBypass) - } - - var listen arvados.URL - for listen = range cluster.Services.GitHTTP.InternalURLs { - break - } - env = append(env, - "GIT_PROJECT_ROOT="+cluster.Git.Repositories, - "GIT_HTTP_EXPORT_ALL=", - "SERVER_ADDR="+listen.Host, - "PATH="+path) - return &gitHandler{ - Handler: cgi.Handler{ - Path: cluster.Git.GitCommand, - Dir: cluster.Git.Repositories, - Env: env, - Args: []string{"http-backend"}, - }, - } -} - -func (h *gitHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - remoteHost, remotePort, err := net.SplitHostPort(r.RemoteAddr) - if err != nil { - ctxlog.FromContext(r.Context()).Errorf("Internal error: SplitHostPort(r.RemoteAddr==%q): %s", r.RemoteAddr, err) - w.WriteHeader(http.StatusInternalServerError) - return - } - - // Copy the wrapped cgi.Handler, so these request-specific - // variables don't leak into the next request. - handlerCopy := h.Handler - handlerCopy.Env = append(handlerCopy.Env, - // In Go1.5 we can skip this, net/http/cgi will do it for us: - "REMOTE_HOST="+remoteHost, - "REMOTE_ADDR="+remoteHost, - "REMOTE_PORT="+remotePort, - // Ideally this would be a real username: - "REMOTE_USER="+r.RemoteAddr, - ) - handlerCopy.ServeHTTP(w, r) -} diff --git a/services/githttpd/git_handler_test.go b/services/githttpd/git_handler_test.go deleted file mode 100644 index ef2ee28e79..0000000000 --- a/services/githttpd/git_handler_test.go +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "context" - "net/http" - "net/http/httptest" - "net/url" - "regexp" - - "git.arvados.org/arvados.git/lib/config" - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/ctxlog" - check "gopkg.in/check.v1" -) - -var _ = check.Suite(&GitHandlerSuite{}) - -type GitHandlerSuite struct { - cluster *arvados.Cluster -} - -func (s *GitHandlerSuite) SetUpTest(c *check.C) { - cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load() - c.Assert(err, check.Equals, nil) - s.cluster, err = cfg.GetCluster("") - c.Assert(err, check.Equals, nil) - - s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{{Host: "localhost:80"}: {}} - s.cluster.Git.GitoliteHome = "/test/ghh" - s.cluster.Git.Repositories = "/" -} - -func (s *GitHandlerSuite) TestEnvVars(c *check.C) { - u, err := url.Parse("git.zzzzz.arvadosapi.com/test") - c.Check(err, check.Equals, nil) - resp := httptest.NewRecorder() - req := &http.Request{ - Method: "GET", - URL: u, - RemoteAddr: "[::1]:12345", - } - h := newGitHandler(context.Background(), s.cluster) - h.(*gitHandler).Path = "/bin/sh" - h.(*gitHandler).Args = []string{"-c", "printf 'Content-Type: text/plain\r\n\r\n'; env"} - - h.ServeHTTP(resp, req) - - c.Check(resp.Code, check.Equals, http.StatusOK) - body := resp.Body.String() - c.Check(body, check.Matches, `(?ms).*^PATH=.*:/test/ghh/bin$.*`) - c.Check(body, check.Matches, `(?ms).*^GITOLITE_HTTP_HOME=/test/ghh$.*`) - c.Check(body, check.Matches, `(?ms).*^GL_BYPASS_ACCESS_CHECKS=1$.*`) - c.Check(body, check.Matches, `(?ms).*^REMOTE_HOST=::1$.*`) - c.Check(body, check.Matches, `(?ms).*^REMOTE_PORT=12345$.*`) - c.Check(body, check.Matches, `(?ms).*^SERVER_ADDR=`+regexp.QuoteMeta("localhost:80")+`$.*`) -} - -func (s *GitHandlerSuite) TestCGIErrorOnSplitHostPortError(c *check.C) { - u, err := url.Parse("git.zzzzz.arvadosapi.com/test") - c.Check(err, check.Equals, nil) - resp := httptest.NewRecorder() - req := &http.Request{ - Method: "GET", - URL: u, - RemoteAddr: "test.bad.address.missing.port", - } - h := newGitHandler(context.Background(), s.cluster) - h.ServeHTTP(resp, req) - c.Check(resp.Code, check.Equals, http.StatusInternalServerError) - c.Check(resp.Body.String(), check.Equals, "") -} diff --git a/services/githttpd/gitolite_test.go b/services/githttpd/gitolite_test.go deleted file mode 100644 index d34c413c1b..0000000000 --- a/services/githttpd/gitolite_test.go +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "io/ioutil" - "os" - "os/exec" - "strings" - - "git.arvados.org/arvados.git/lib/config" - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/ctxlog" - check "gopkg.in/check.v1" -) - -var _ = check.Suite(&GitoliteSuite{}) - -// GitoliteSuite tests need an API server, an arvados-git-httpd -// server, and a repository hosted by gitolite. -type GitoliteSuite struct { - IntegrationSuite - gitoliteHome string -} - -func (s *GitoliteSuite) SetUpTest(c *check.C) { - var err error - s.gitoliteHome, err = ioutil.TempDir("", "githttp") - c.Assert(err, check.Equals, nil) - - runGitolite := func(prog string, args ...string) { - c.Log(prog, " ", args) - cmd := exec.Command(prog, args...) - cmd.Dir = s.gitoliteHome - cmd.Env = []string{"HOME=" + s.gitoliteHome} - for _, e := range os.Environ() { - if !strings.HasPrefix(e, "HOME=") { - cmd.Env = append(cmd.Env, e) - } - } - diags, err := cmd.CombinedOutput() - c.Log(string(diags)) - c.Assert(err, check.Equals, nil) - } - - runGitolite("gitolite", "setup", "--admin", "root") - - s.tmpRepoRoot = s.gitoliteHome + "/repositories" - - cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load() - c.Assert(err, check.Equals, nil) - s.cluster, err = cfg.GetCluster("") - c.Assert(err, check.Equals, nil) - - s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{{Host: "localhost:0"}: {}} - s.cluster.TLS.Insecure = true - s.cluster.Git.GitCommand = "/usr/share/gitolite3/gitolite-shell" - s.cluster.Git.GitoliteHome = s.gitoliteHome - s.cluster.Git.Repositories = s.tmpRepoRoot - - s.IntegrationSuite.SetUpTest(c) - - // Install the gitolite hooks in the bare repo we made in - // (*IntegrationTest)SetUpTest() -- see 2.2.4 at - // http://gitolite.com/gitolite/gitolite.html - runGitolite("gitolite", "setup") -} - -func (s *GitoliteSuite) TearDownTest(c *check.C) { - // We really want Unsetenv here, but it's not worth forcing an - // upgrade to Go 1.4. - os.Setenv("GITOLITE_HTTP_HOME", "") - os.Setenv("GL_BYPASS_ACCESS_CHECKS", "") - if s.gitoliteHome != "" { - err := os.RemoveAll(s.gitoliteHome) - c.Check(err, check.Equals, nil) - } - s.IntegrationSuite.TearDownTest(c) -} - -func (s *GitoliteSuite) TestFetch(c *check.C) { - err := s.RunGit(c, activeToken, "fetch", "active/foo.git", "refs/heads/main") - c.Check(err, check.Equals, nil) -} - -func (s *GitoliteSuite) TestFetchUnreadable(c *check.C) { - err := s.RunGit(c, anonymousToken, "fetch", "active/foo.git") - c.Check(err, check.ErrorMatches, `.* not found.*`) -} - -func (s *GitoliteSuite) TestPush(c *check.C) { - err := s.RunGit(c, activeToken, "push", "active/foo.git", "main:gitolite-push") - c.Check(err, check.Equals, nil) - - // Check that the commit hash appears in the gitolite log, as - // assurance that the gitolite hooks really did run. - - sha1, err := exec.Command("git", "--git-dir", s.tmpWorkdir+"/.git", - "log", "-n1", "--format=%H").CombinedOutput() - c.Logf("git-log in workdir: %q", string(sha1)) - c.Assert(err, check.Equals, nil) - c.Assert(len(sha1), check.Equals, 41) - - gitoliteLog, err := exec.Command("grep", "-r", string(sha1[:40]), s.gitoliteHome+"/.gitolite/logs").CombinedOutput() - c.Check(err, check.Equals, nil) - c.Logf("gitolite log message: %q", string(gitoliteLog)) -} - -func (s *GitoliteSuite) TestPushUnwritable(c *check.C) { - err := s.RunGit(c, spectatorToken, "push", "active/foo.git", "main:gitolite-push-fail") - c.Check(err, check.ErrorMatches, `.*HTTP (code = )?403.*`) -} diff --git a/services/githttpd/integration_test.go b/services/githttpd/integration_test.go deleted file mode 100644 index c819272d3e..0000000000 --- a/services/githttpd/integration_test.go +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "context" - "errors" - "io/ioutil" - "os" - "os/exec" - "strings" - "testing" - - "git.arvados.org/arvados.git/lib/config" - "git.arvados.org/arvados.git/sdk/go/arvados" - "git.arvados.org/arvados.git/sdk/go/arvadostest" - "git.arvados.org/arvados.git/sdk/go/ctxlog" - "git.arvados.org/arvados.git/sdk/go/httpserver" - check "gopkg.in/check.v1" -) - -// Gocheck boilerplate -func Test(t *testing.T) { - check.TestingT(t) -} - -// IntegrationSuite tests need an API server and an arvados-git-httpd -// server. See GitSuite and GitoliteSuite. -type IntegrationSuite struct { - tmpRepoRoot string - tmpWorkdir string - testServer *httpserver.Server - cluster *arvados.Cluster -} - -func (s *IntegrationSuite) SetUpTest(c *check.C) { - arvadostest.ResetEnv() - - var err error - if s.tmpRepoRoot == "" { - s.tmpRepoRoot, err = ioutil.TempDir("", "githttp") - c.Assert(err, check.Equals, nil) - } - s.tmpWorkdir, err = ioutil.TempDir("", "githttp") - c.Assert(err, check.Equals, nil) - _, err = exec.Command("git", "init", "--bare", s.tmpRepoRoot+"/zzzzz-s0uqq-382brsig8rp3666.git").Output() - c.Assert(err, check.Equals, nil) - // we need git 2.28 to specify the initial branch with -b; Buster only has 2.20; so we do it in 2 steps - _, err = exec.Command("git", "init", s.tmpWorkdir).Output() - c.Assert(err, check.Equals, nil) - _, err = exec.Command("sh", "-c", "cd "+s.tmpWorkdir+" && git checkout -b main").Output() - c.Assert(err, check.Equals, nil) - _, err = exec.Command("sh", "-c", "cd "+s.tmpWorkdir+" && echo initial >initial && git add initial && git -c user.name=Initial -c user.email=Initial commit -am 'foo: initial commit'").CombinedOutput() - c.Assert(err, check.Equals, nil) - _, err = exec.Command("sh", "-c", "cd "+s.tmpWorkdir+" && git push "+s.tmpRepoRoot+"/zzzzz-s0uqq-382brsig8rp3666.git main:main").CombinedOutput() - c.Assert(err, check.Equals, nil) - _, err = exec.Command("sh", "-c", "cd "+s.tmpWorkdir+" && echo work >work && git add work && git -c user.name=Foo -c user.email=Foo commit -am 'workdir: test'").CombinedOutput() - c.Assert(err, check.Equals, nil) - - if s.cluster == nil { - cfg, err := config.NewLoader(nil, ctxlog.TestLogger(c)).Load() - c.Assert(err, check.Equals, nil) - s.cluster, err = cfg.GetCluster("") - c.Assert(err, check.Equals, nil) - - s.cluster.Services.GitHTTP.InternalURLs = map[arvados.URL]arvados.ServiceInstance{{Host: "localhost:0"}: {}} - s.cluster.TLS.Insecure = true - s.cluster.Git.GitCommand = "/usr/bin/git" - s.cluster.Git.Repositories = s.tmpRepoRoot - s.cluster.ManagementToken = arvadostest.ManagementToken - } - - s.testServer = &httpserver.Server{} - s.testServer.Handler = httpserver.LogRequests(newHandler(context.Background(), s.cluster, "", nil)) - err = s.testServer.Start() - c.Assert(err, check.Equals, nil) - - _, err = exec.Command("git", "config", - "--file", s.tmpWorkdir+"/.git/config", - "credential.http://"+s.testServer.Addr+"/.helper", - "!cred(){ cat >/dev/null; if [ \"$1\" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred").Output() - c.Assert(err, check.Equals, nil) - _, err = exec.Command("git", "config", - "--file", s.tmpWorkdir+"/.git/config", - "credential.http://"+s.testServer.Addr+"/.username", - "none").Output() - c.Assert(err, check.Equals, nil) - - // Clear ARVADOS_API_* env vars before starting up the server, - // to make sure arvados-git-httpd doesn't use them or complain - // about them being missing. - os.Unsetenv("ARVADOS_API_HOST") - os.Unsetenv("ARVADOS_API_HOST_INSECURE") - os.Unsetenv("ARVADOS_API_TOKEN") -} - -func (s *IntegrationSuite) TearDownTest(c *check.C) { - var err error - if s.testServer != nil { - err = s.testServer.Close() - } - c.Check(err, check.Equals, nil) - s.testServer = nil - - if s.tmpRepoRoot != "" { - err = os.RemoveAll(s.tmpRepoRoot) - c.Check(err, check.Equals, nil) - } - s.tmpRepoRoot = "" - - if s.tmpWorkdir != "" { - err = os.RemoveAll(s.tmpWorkdir) - c.Check(err, check.Equals, nil) - } - s.tmpWorkdir = "" - - s.cluster = nil -} - -func (s *IntegrationSuite) RunGit(c *check.C, token, gitCmd, repo string, args ...string) error { - cwd, err := os.Getwd() - c.Assert(err, check.Equals, nil) - defer os.Chdir(cwd) - os.Chdir(s.tmpWorkdir) - - gitargs := append([]string{ - gitCmd, "http://" + s.testServer.Addr + "/" + repo, - }, args...) - cmd := exec.Command("git", gitargs...) - cmd.Env = append(os.Environ(), "ARVADOS_API_TOKEN="+token) - w, err := cmd.StdinPipe() - c.Assert(err, check.Equals, nil) - w.Close() - output, err := cmd.CombinedOutput() - c.Log("git ", gitargs, " => ", err) - c.Log(string(output)) - if err != nil && len(output) > 0 { - // If messages appeared on stderr, they are more - // helpful than the err returned by CombinedOutput(). - // - // Easier to match error strings without newlines: - err = errors.New(strings.Replace(string(output), "\n", " // ", -1)) - } - return err -} diff --git a/services/githttpd/server_test.go b/services/githttpd/server_test.go deleted file mode 100644 index 02c13a3112..0000000000 --- a/services/githttpd/server_test.go +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) The Arvados Authors. All rights reserved. -// -// SPDX-License-Identifier: AGPL-3.0 - -package githttpd - -import ( - "os" - "os/exec" - - check "gopkg.in/check.v1" -) - -var _ = check.Suite(&GitSuite{}) - -const ( - spectatorToken = "zw2f4gwx8hw8cjre7yp6v1zylhrhn3m5gvjq73rtpwhmknrybu" - activeToken = "3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi" - anonymousToken = "4kg6k6lzmp9kj4cpkcoxie964cmvjahbt4fod9zru44k4jqdmi" - expiredToken = "2ym314ysp27sk7h943q6vtc378srb06se3pq6ghurylyf3pdmx" -) - -type GitSuite struct { - IntegrationSuite -} - -func (s *GitSuite) TestPathVariants(c *check.C) { - s.makeArvadosRepo(c) - for _, repo := range []string{"active/foo.git", "active/foo/.git", "arvados.git", "arvados/.git"} { - err := s.RunGit(c, spectatorToken, "fetch", repo, "refs/heads/main") - c.Assert(err, check.Equals, nil) - } -} - -func (s *GitSuite) TestReadonly(c *check.C) { - err := s.RunGit(c, spectatorToken, "fetch", "active/foo.git", "refs/heads/main") - c.Assert(err, check.Equals, nil) - err = s.RunGit(c, spectatorToken, "push", "active/foo.git", "main:newbranchfail") - c.Assert(err, check.ErrorMatches, `.*HTTP (code = )?403.*`) - _, err = os.Stat(s.tmpRepoRoot + "/zzzzz-s0uqq-382brsig8rp3666.git/refs/heads/newbranchfail") - c.Assert(err, check.FitsTypeOf, &os.PathError{}) -} - -func (s *GitSuite) TestReadwrite(c *check.C) { - err := s.RunGit(c, activeToken, "fetch", "active/foo.git", "refs/heads/main") - c.Assert(err, check.Equals, nil) - err = s.RunGit(c, activeToken, "push", "active/foo.git", "main:newbranch") - c.Assert(err, check.Equals, nil) - _, err = os.Stat(s.tmpRepoRoot + "/zzzzz-s0uqq-382brsig8rp3666.git/refs/heads/newbranch") - c.Assert(err, check.Equals, nil) -} - -func (s *GitSuite) TestNonexistent(c *check.C) { - err := s.RunGit(c, spectatorToken, "fetch", "thisrepodoesnotexist.git", "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* not found.*`) -} - -func (s *GitSuite) TestMissingGitdirReadableRepository(c *check.C) { - err := s.RunGit(c, activeToken, "fetch", "active/foo2.git", "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* not found.*`) -} - -func (s *GitSuite) TestNoPermission(c *check.C) { - for _, repo := range []string{"active/foo.git", "active/foo/.git"} { - err := s.RunGit(c, anonymousToken, "fetch", repo, "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* not found.*`) - } -} - -func (s *GitSuite) TestExpiredToken(c *check.C) { - for _, repo := range []string{"active/foo.git", "active/foo/.git"} { - err := s.RunGit(c, expiredToken, "fetch", repo, "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* (500 while accessing|requested URL returned error: 500).*`) - } -} - -func (s *GitSuite) TestInvalidToken(c *check.C) { - for _, repo := range []string{"active/foo.git", "active/foo/.git"} { - err := s.RunGit(c, "s3cr3tp@ssw0rd", "fetch", repo, "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* requested URL returned error.*`) - } -} - -func (s *GitSuite) TestShortToken(c *check.C) { - for _, repo := range []string{"active/foo.git", "active/foo/.git"} { - err := s.RunGit(c, "s3cr3t", "fetch", repo, "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.* (500 while accessing|requested URL returned error: 500).*`) - } -} - -func (s *GitSuite) TestShortTokenBadReq(c *check.C) { - for _, repo := range []string{"bogus"} { - err := s.RunGit(c, "s3cr3t", "fetch", repo, "refs/heads/main") - c.Assert(err, check.ErrorMatches, `.*not found.*`) - } -} - -// Make a bare arvados repo at {tmpRepoRoot}/arvados.git -func (s *GitSuite) makeArvadosRepo(c *check.C) { - msg, err := exec.Command("git", "init", "--bare", s.tmpRepoRoot+"/zzzzz-s0uqq-arvadosrepo0123.git").CombinedOutput() - c.Log(string(msg)) - c.Assert(err, check.Equals, nil) - msg, err = exec.Command("git", "--git-dir", s.tmpRepoRoot+"/zzzzz-s0uqq-arvadosrepo0123.git", "fetch", "../../.git", "HEAD:main").CombinedOutput() - c.Log(string(msg)) - c.Assert(err, check.Equals, nil) -} diff --git a/services/keep-balance/integration_test.go b/services/keep-balance/integration_test.go index 20d0040b1f..b4bf423cd7 100644 --- a/services/keep-balance/integration_test.go +++ b/services/keep-balance/integration_test.go @@ -86,7 +86,7 @@ func (s *integrationSuite) TestBalanceAPIFixtures(c *check.C) { for iter := 0; iter < 20; iter++ { logBuf.Reset() logger := logrus.New() - logger.Out = io.MultiWriter(&logBuf, os.Stderr) + logger.Out = io.MultiWriter(&logBuf, ctxlog.LogWriter(c.Log)) opts := RunOptions{ CommitConfirmedFields: true, Logger: logger, diff --git a/services/keep-web/cache.go b/services/keep-web/cache.go index d443bc0829..b5b6cc4fa5 100644 --- a/services/keep-web/cache.go +++ b/services/keep-web/cache.go @@ -179,6 +179,7 @@ func (c *cache) checkout(token string) (*cachedSession, error) { } client.AuthToken = token client.Timeout = time.Minute + client.Logger = c.logger // A non-empty origin header tells controller to // prioritize our traffic as interactive, which is // true most of the time. @@ -188,11 +189,13 @@ func (c *cache) checkout(token string) (*cachedSession, error) { if err != nil { return nil, err } + kc := keepclient.New(arvadosclient) + kc.DiskCacheSize = c.cluster.Collections.WebDAVCache.DiskCacheSize sess = &cachedSession{ cache: c, client: client, arvadosclient: arvadosclient, - keepclient: keepclient.New(arvadosclient), + keepclient: kc, } c.sessions[token] = sess } diff --git a/services/keep-web/handler.go b/services/keep-web/handler.go index cdd51f0bb7..b9250efec7 100644 --- a/services/keep-web/handler.go +++ b/services/keep-web/handler.go @@ -430,11 +430,26 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { return } defer f.Close() - defer sess.Release() collectionDir, sessionFS, session, tokenUser = f, fs, sess, user break } + + // releaseSession() is equivalent to session.Release() except + // that it's a no-op if (1) session is nil, or (2) it has + // already been called. + // + // This way, we can do a defer call here to ensure it gets + // called in all code paths, and also call it inline (see + // below) in the cases where we want to release the lock + // before returning. + releaseSession := func() {} + if session != nil { + var releaseSessionOnce sync.Once + releaseSession = func() { releaseSessionOnce.Do(func() { session.Release() }) } + } + defer releaseSession() + if forceReload && collectionDir != nil { err := collectionDir.Sync() if err != nil { @@ -522,6 +537,7 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { if r.Method == http.MethodGet || r.Method == http.MethodHead { targetfnm := fsprefix + strings.Join(pathParts[stripParts:], "/") if fi, err := sessionFS.Stat(targetfnm); err == nil && fi.IsDir() { + releaseSession() // because we won't be writing anything if !strings.HasSuffix(r.URL.Path, "/") { h.seeOtherWithCookie(w, r, r.URL.Path+"/", credentialsOK) } else { @@ -591,6 +607,15 @@ func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) { collectionDir.Splice(snap) return nil }} + } else { + // When writing, we need to block session renewal + // until we're finished, in order to guarantee the + // effect of the write is visible in future responses. + // But if we're not writing, we can release the lock + // early. This enables us to keep renewing sessions + // and processing more requests even if a slow client + // takes a long time to download a large file. + releaseSession() } if r.Method == http.MethodGet { applyContentDispositionHdr(w, r, basename, attachment) diff --git a/services/keep-web/server_test.go b/services/keep-web/server_test.go index f79df20212..0308f949f4 100644 --- a/services/keep-web/server_test.go +++ b/services/keep-web/server_test.go @@ -518,7 +518,7 @@ func (s *IntegrationSuite) TestMetrics(c *check.C) { allmetrics, err := ioutil.ReadAll(resp.Body) c.Check(err, check.IsNil) - c.Check(string(allmetrics), check.Matches, `(?ms).*\narvados_keepweb_download_apparent_backend_speed_bucket{size_range="0",le="1e\+06"} 4\n.*`) + c.Check(string(allmetrics), check.Matches, `(?ms).*\narvados_keepweb_download_apparent_backend_speed_bucket{size_range="0",le="\+Inf"} 4\n.*`) c.Check(string(allmetrics), check.Matches, `(?ms).*\narvados_keepweb_download_speed_bucket{size_range="0",le="\+Inf"} 4\n.*`) c.Check(string(allmetrics), check.Matches, `(?ms).*\narvados_keepweb_upload_speed_bucket{size_range="0",le="\+Inf"} 2\n.*`) c.Check(string(allmetrics), check.Matches, `(?ms).*\narvados_keepweb_upload_sync_delay_seconds_bucket{size_range="0",le="10"} 2\n.*`) diff --git a/services/keepproxy/keepproxy.go b/services/keepproxy/keepproxy.go index 39ffd45cbe..97a5ad6592 100644 --- a/services/keepproxy/keepproxy.go +++ b/services/keepproxy/keepproxy.go @@ -23,6 +23,7 @@ import ( "git.arvados.org/arvados.git/sdk/go/health" "git.arvados.org/arvados.git/sdk/go/httpserver" "git.arvados.org/arvados.git/sdk/go/keepclient" + "git.arvados.org/arvados.git/services/keepstore" "github.com/gorilla/mux" lru "github.com/hashicorp/golang-lru" "github.com/prometheus/client_golang/prometheus" @@ -271,10 +272,9 @@ func (h *proxyHandler) checkLoop(resp http.ResponseWriter, req *http.Request) er } func setCORSHeaders(resp http.ResponseWriter) { - resp.Header().Set("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, OPTIONS") - resp.Header().Set("Access-Control-Allow-Origin", "*") - resp.Header().Set("Access-Control-Allow-Headers", "Authorization, Content-Length, Content-Type, X-Keep-Desired-Replicas") - resp.Header().Set("Access-Control-Max-Age", "86486400") + keepstore.SetCORSHeaders(resp) + acam := "Access-Control-Allow-Methods" + resp.Header().Set(acam, resp.Header().Get(acam)+", POST") } type invalidPathHandler struct{} @@ -419,9 +419,9 @@ func (h *proxyHandler) Put(resp http.ResponseWriter, req *http.Request) { locatorIn := mux.Vars(req)["locator"] // Check if the client specified storage classes - if req.Header.Get("X-Keep-Storage-Classes") != "" { + if req.Header.Get(keepclient.XKeepStorageClasses) != "" { var scl []string - for _, sc := range strings.Split(req.Header.Get("X-Keep-Storage-Classes"), ",") { + for _, sc := range strings.Split(req.Header.Get(keepclient.XKeepStorageClasses), ",") { scl = append(scl, strings.Trim(sc, " ")) } kc.SetStorageClasses(scl) diff --git a/services/keepproxy/keepproxy_test.go b/services/keepproxy/keepproxy_test.go index 2c73e2d104..ea8c9ba6ca 100644 --- a/services/keepproxy/keepproxy_test.go +++ b/services/keepproxy/keepproxy_test.go @@ -558,14 +558,14 @@ func (s *ServerRequiredSuite) TestCorsHeaders(c *C) { body, err := ioutil.ReadAll(resp.Body) c.Check(err, IsNil) c.Check(string(body), Equals, "") - c.Check(resp.Header.Get("Access-Control-Allow-Methods"), Equals, "GET, HEAD, POST, PUT, OPTIONS") + c.Check(resp.Header.Get("Access-Control-Allow-Methods"), Equals, "GET, HEAD, PUT, OPTIONS, POST") c.Check(resp.Header.Get("Access-Control-Allow-Origin"), Equals, "*") } { resp, err := http.Get(fmt.Sprintf("http://%s/%x+3", srv.Addr, md5.Sum([]byte("foo")))) c.Check(err, Equals, nil) - c.Check(resp.Header.Get("Access-Control-Allow-Headers"), Equals, "Authorization, Content-Length, Content-Type, X-Keep-Desired-Replicas") + c.Check(resp.Header.Get("Access-Control-Allow-Headers"), Equals, "Authorization, Content-Length, Content-Type, X-Keep-Desired-Replicas, X-Keep-Signature, X-Keep-Storage-Classes") c.Check(resp.Header.Get("Access-Control-Allow-Origin"), Equals, "*") } } diff --git a/services/keepstore/router.go b/services/keepstore/router.go index 0c8182c6ea..dfb2ace3a7 100644 --- a/services/keepstore/router.go +++ b/services/keepstore/router.go @@ -19,6 +19,7 @@ import ( "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/auth" "git.arvados.org/arvados.git/sdk/go/httpserver" + "git.arvados.org/arvados.git/sdk/go/keepclient" "github.com/gorilla/mux" ) @@ -57,9 +58,11 @@ func newRouter(keepstore *keepstore, puller *puller, trasher *trasher) service.H touch.HandleFunc(locatorPath, adminonly(rtr.handleBlockTouch)) delete := r.Methods(http.MethodDelete).Subrouter() delete.HandleFunc(locatorPath, adminonly(rtr.handleBlockTrash)) + options := r.Methods(http.MethodOptions).Subrouter() + options.NewRoute().PathPrefix(`/`).HandlerFunc(rtr.handleOptions) r.NotFoundHandler = http.HandlerFunc(rtr.handleBadRequest) r.MethodNotAllowedHandler = http.HandlerFunc(rtr.handleBadRequest) - rtr.Handler = auth.LoadToken(r) + rtr.Handler = corsHandler(auth.LoadToken(r)) return rtr } @@ -75,11 +78,11 @@ func (rtr *router) handleBlockRead(w http.ResponseWriter, req *http.Request) { // Intervening proxies must not return a cached GET response // to a prior request if a X-Keep-Signature request header has // been added or changed. - w.Header().Add("Vary", "X-Keep-Signature") + w.Header().Add("Vary", keepclient.XKeepSignature) var localLocator func(string) - if strings.SplitN(req.Header.Get("X-Keep-Signature"), ",", 2)[0] == "local" { + if strings.SplitN(req.Header.Get(keepclient.XKeepSignature), ",", 2)[0] == "local" { localLocator = func(locator string) { - w.Header().Set("X-Keep-Locator", locator) + w.Header().Set(keepclient.XKeepLocator, locator) } } out := w @@ -107,20 +110,20 @@ func (rtr *router) handleBlockRead(w http.ResponseWriter, req *http.Request) { func (rtr *router) handleBlockWrite(w http.ResponseWriter, req *http.Request) { dataSize, _ := strconv.Atoi(req.Header.Get("Content-Length")) - replicas, _ := strconv.Atoi(req.Header.Get("X-Arvados-Replicas-Desired")) + replicas, _ := strconv.Atoi(req.Header.Get(keepclient.XKeepDesiredReplicas)) resp, err := rtr.keepstore.BlockWrite(req.Context(), arvados.BlockWriteOptions{ Hash: mux.Vars(req)["locator"], Reader: req.Body, DataSize: dataSize, RequestID: req.Header.Get("X-Request-Id"), - StorageClasses: trimSplit(req.Header.Get("X-Keep-Storage-Classes"), ","), + StorageClasses: trimSplit(req.Header.Get(keepclient.XKeepStorageClasses), ","), Replicas: replicas, }) if err != nil { rtr.handleError(w, req, err) return } - w.Header().Set("X-Keep-Replicas-Stored", fmt.Sprintf("%d", resp.Replicas)) + w.Header().Set(keepclient.XKeepReplicasStored, fmt.Sprintf("%d", resp.Replicas)) scc := "" for k, n := range resp.StorageClasses { if n > 0 { @@ -130,7 +133,7 @@ func (rtr *router) handleBlockWrite(w http.ResponseWriter, req *http.Request) { scc += fmt.Sprintf("%s=%d", k, n) } } - w.Header().Set("X-Keep-Storage-Classes-Confirmed", scc) + w.Header().Set(keepclient.XKeepStorageClassesConfirmed, scc) w.WriteHeader(http.StatusOK) fmt.Fprintln(w, resp.Locator) } @@ -210,6 +213,9 @@ func (rtr *router) handleBadRequest(w http.ResponseWriter, req *http.Request) { http.Error(w, "Bad Request", http.StatusBadRequest) } +func (rtr *router) handleOptions(w http.ResponseWriter, req *http.Request) { +} + func (rtr *router) handleError(w http.ResponseWriter, req *http.Request, err error) { if req.Context().Err() != nil { w.WriteHeader(499) @@ -274,3 +280,24 @@ type discardWrite struct { func (discardWrite) Write(p []byte) (int, error) { return len(p), nil } + +func corsHandler(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + SetCORSHeaders(w) + h.ServeHTTP(w, r) + }) +} + +var corsHeaders = map[string]string{ + "Access-Control-Allow-Methods": "GET, HEAD, PUT, OPTIONS", + "Access-Control-Allow-Origin": "*", + "Access-Control-Allow-Headers": "Authorization, Content-Length, Content-Type, " + keepclient.XKeepDesiredReplicas + ", " + keepclient.XKeepSignature + ", " + keepclient.XKeepStorageClasses, + "Access-Control-Expose-Headers": keepclient.XKeepLocator + ", " + keepclient.XKeepReplicasStored + ", " + keepclient.XKeepStorageClassesConfirmed, + "Access-Control-Max-Age": "86486400", +} + +func SetCORSHeaders(w http.ResponseWriter) { + for k, v := range corsHeaders { + w.Header().Set(k, v) + } +} diff --git a/services/keepstore/router_test.go b/services/keepstore/router_test.go index 15a055d55e..215033b48e 100644 --- a/services/keepstore/router_test.go +++ b/services/keepstore/router_test.go @@ -78,22 +78,26 @@ func (s *routerSuite) TestBlockRead_Token(c *C) { resp := call(router, "GET", "http://example/"+locSigned, "", nil, nil) c.Check(resp.Code, Equals, http.StatusUnauthorized) c.Check(resp.Body.String(), Matches, "no token provided in Authorization header\n") + checkCORSHeaders(c, resp.Header()) // Different token => invalid signature resp = call(router, "GET", "http://example/"+locSigned, "badtoken", nil, nil) c.Check(resp.Code, Equals, http.StatusBadRequest) c.Check(resp.Body.String(), Equals, "invalid signature\n") + checkCORSHeaders(c, resp.Header()) // Correct token resp = call(router, "GET", "http://example/"+locSigned, arvadostest.ActiveTokenV2, nil, nil) c.Check(resp.Code, Equals, http.StatusOK) c.Check(resp.Body.String(), Equals, "foo") + checkCORSHeaders(c, resp.Header()) // HEAD resp = call(router, "HEAD", "http://example/"+locSigned, arvadostest.ActiveTokenV2, nil, nil) c.Check(resp.Code, Equals, http.StatusOK) c.Check(resp.Result().ContentLength, Equals, int64(3)) c.Check(resp.Body.String(), Equals, "") + checkCORSHeaders(c, resp.Header()) } // As a special case we allow HEAD requests that only provide a hash @@ -165,13 +169,16 @@ func (s *routerSuite) TestBlockRead_ChecksumMismatch(c *C) { } c.Check(resp.Body.Len(), Not(Equals), len(gooddata)) c.Check(resp.Result().ContentLength, Equals, int64(len(gooddata))) + checkCORSHeaders(c, resp.Header()) resp = call(router, "HEAD", "http://example/"+locSigned, arvadostest.ActiveTokenV2, nil, nil) c.Check(resp.Code, Equals, http.StatusBadGateway) + checkCORSHeaders(c, resp.Header()) hashSigned := router.keepstore.signLocator(arvadostest.ActiveTokenV2, hash) resp = call(router, "HEAD", "http://example/"+hashSigned, arvadostest.ActiveTokenV2, nil, nil) c.Check(resp.Code, Equals, http.StatusBadGateway) + checkCORSHeaders(c, resp.Header()) } } @@ -181,6 +188,7 @@ func (s *routerSuite) TestBlockWrite(c *C) { resp := call(router, "PUT", "http://example/"+fooHash, arvadostest.ActiveTokenV2, []byte("foo"), nil) c.Check(resp.Code, Equals, http.StatusOK) + checkCORSHeaders(c, resp.Header()) locator := strings.TrimSpace(resp.Body.String()) resp = call(router, "GET", "http://example/"+locator, arvadostest.ActiveTokenV2, nil, nil) @@ -192,7 +200,7 @@ func (s *routerSuite) TestBlockWrite_Headers(c *C) { router, cancel := testRouter(c, s.cluster, nil) defer cancel() - resp := call(router, "PUT", "http://example/"+fooHash, arvadostest.ActiveTokenV2, []byte("foo"), http.Header{"X-Arvados-Replicas-Desired": []string{"2"}}) + resp := call(router, "PUT", "http://example/"+fooHash, arvadostest.ActiveTokenV2, []byte("foo"), http.Header{"X-Keep-Desired-Replicas": []string{"2"}}) c.Check(resp.Code, Equals, http.StatusOK) c.Check(resp.Header().Get("X-Keep-Replicas-Stored"), Equals, "1") c.Check(sortCommaSeparated(resp.Header().Get("X-Keep-Storage-Classes-Confirmed")), Equals, "testclass1=1") @@ -469,7 +477,6 @@ func (s *routerSuite) TestIndex(c *C) { c.Check(resp.Code, Equals, http.StatusOK) c.Check(strings.Split(resp.Body.String(), "\n"), HasLen, 5) } - } // Check that the context passed to a volume method gets cancelled @@ -500,6 +507,19 @@ func (s *routerSuite) TestCancelOnDisconnect(c *C) { c.Check(resp.Code, Equals, 499) } +func (s *routerSuite) TestCORSPreflight(c *C) { + router, cancel := testRouter(c, s.cluster, nil) + defer cancel() + + for _, path := range []string{"/", "/whatever", "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+123"} { + c.Logf("=== %s", path) + resp := call(router, http.MethodOptions, "http://example"+path, arvadostest.ActiveTokenV2, nil, nil) + c.Check(resp.Code, Equals, http.StatusOK) + c.Check(resp.Body.String(), Equals, "") + checkCORSHeaders(c, resp.Header()) + } +} + func call(handler http.Handler, method, path, tok string, body []byte, hdr http.Header) *httptest.ResponseRecorder { resp := httptest.NewRecorder() req, err := http.NewRequest(method, path, bytes.NewReader(body)) @@ -515,3 +535,10 @@ func call(handler http.Handler, method, path, tok string, body []byte, hdr http. handler.ServeHTTP(resp, req) return resp } + +func checkCORSHeaders(c *C, h http.Header) { + c.Check(h.Get("Access-Control-Allow-Methods"), Equals, "GET, HEAD, PUT, OPTIONS") + c.Check(h.Get("Access-Control-Allow-Origin"), Equals, "*") + c.Check(h.Get("Access-Control-Allow-Headers"), Equals, "Authorization, Content-Length, Content-Type, X-Keep-Desired-Replicas, X-Keep-Signature, X-Keep-Storage-Classes") + c.Check(h.Get("Access-Control-Expose-Headers"), Equals, "X-Keep-Locator, X-Keep-Replicas-Stored, X-Keep-Storage-Classes-Confirmed") +} diff --git a/services/workbench2/.gitignore b/services/workbench2/.gitignore index 7358d62706..9093202ff8 100644 --- a/services/workbench2/.gitignore +++ b/services/workbench2/.gitignore @@ -33,6 +33,7 @@ yarn-error.log* .idea .vscode +.eslintcache /public/config.json /public/_health/ diff --git a/services/workbench2/cypress/e2e/banner-tooltip.cy.js b/services/workbench2/cypress/e2e/banner-tooltip.cy.js index f8100961aa..ba503934bd 100644 --- a/services/workbench2/cypress/e2e/banner-tooltip.cy.js +++ b/services/workbench2/cypress/e2e/banner-tooltip.cy.js @@ -80,21 +80,24 @@ describe('Banner / tooltip tests', function () { cy.loginAs(adminUser); cy.waitForDom(); + cy.waitForDom().get('[data-cy=confirmation-dialog]', {timeout: 10000}).should('be.visible'); cy.get('[data-cy=confirmation-dialog-ok-btn]').click(); - cy.waitForDom(); - cy.get('[data-cy=confirmation-dialog]').should('not.exist'); + cy.waitForDom().get('[data-cy=confirmation-dialog]', {timeout: 10000}).should('not.exist'); cy.get('[title=Notifications]').click(); cy.get('li').contains('Restore Banner').click(); - cy.get('[data-cy=confirmation-dialog-ok-btn]').should('be.visible'); + cy.waitForDom().get('[data-cy=confirmation-dialog-ok-btn]', {timeout: 10000}).should('be.visible'); }); it('should show tooltips and remove tooltips as localStorage key is present', () => { cy.loginAs(adminUser); + cy.waitForDom(); + cy.waitForDom().get('[data-cy=confirmation-dialog]', {timeout: 10000}).should('be.visible'); cy.get('[data-cy=confirmation-dialog-ok-btn]').click(); + cy.waitForDom().get('[data-cy=confirmation-dialog]', {timeout: 10000}).should('not.exist'); cy.contains('This allows you to navigate through the app').should('not.exist'); // This content comes from tooltips.txt cy.get('[data-cy=side-panel-tree]').trigger('mouseover'); diff --git a/services/workbench2/cypress/e2e/collection.cy.js b/services/workbench2/cypress/e2e/collection.cy.js index 38a0c973fd..20ecf11c09 100644 --- a/services/workbench2/cypress/e2e/collection.cy.js +++ b/services/workbench2/cypress/e2e/collection.cy.js @@ -143,7 +143,7 @@ describe("Collection panel tests", function () { cy.get("[data-cy=name-field]").within(() => { cy.get("input").type(" renamed"); }); - cy.get("[data-cy=form-submit-btn]").click(); + cy.get("[data-cy=form-submit-btn]").click({timeout: 10000}); }); cy.get("[data-cy=form-dialog]").should("not.exist"); // Attempt to rename the collection with the duplicate name diff --git a/services/workbench2/cypress/e2e/search.cy.js b/services/workbench2/cypress/e2e/search.cy.js index 094a3f618c..4e5aa31f4d 100644 --- a/services/workbench2/cypress/e2e/search.cy.js +++ b/services/workbench2/cypress/e2e/search.cy.js @@ -215,8 +215,6 @@ describe("Search tests", function () { DispatchCloud: { ExternalURL: "" }, DispatchLSF: { ExternalURL: "" }, DispatchSLURM: { ExternalURL: "" }, - GitHTTP: { ExternalURL: "https://xxxxx.fakecluster.tld:39105/" }, - GitSSH: { ExternalURL: "" }, Health: { ExternalURL: "https://xxxxx.fakecluster.tld:42915/" }, Keepbalance: { ExternalURL: "" }, Keepproxy: { ExternalURL: "https://xxxxx.fakecluster.tld:46773/" }, diff --git a/services/workbench2/cypress/e2e/sharing.cy.js b/services/workbench2/cypress/e2e/sharing.cy.js index 05a7d470bf..4cb7e48785 100644 --- a/services/workbench2/cypress/e2e/sharing.cy.js +++ b/services/workbench2/cypress/e2e/sharing.cy.js @@ -31,7 +31,7 @@ describe('Sharing tests', function () { cy.get('main').contains(sharedCollection.name).rightclick(); cy.get('[data-cy=context-menu]').within(() => { - cy.contains('Share').click(); + cy.contains('Share').click({ waitForAnimations: false }); }); cy.get('.sharing-dialog').within(() => { cy.contains('Sharing URLs').click(); @@ -63,7 +63,7 @@ describe('Sharing tests', function () { cy.contains('Refresh').click(); cy.get('main').contains(mySharedWritableProject.name).rightclick(); cy.get('[data-cy=context-menu]').within(() => { - cy.contains('Share').click(); + cy.contains('Share').click({ waitForAnimations: false }); }); cy.get('[id="select-permissions"]').as('selectPermissions'); cy.get('@selectPermissions').click(); @@ -73,7 +73,7 @@ describe('Sharing tests', function () { cy.get('[role=tooltip]').click(); cy.get('@sharingDialog').within(() => { cy.get('[data-cy=add-invited-people]').click(); - cy.contains('Close').click(); + cy.contains('Close').click({ waitForAnimations: false }); }); }); @@ -84,14 +84,14 @@ describe('Sharing tests', function () { cy.contains('Refresh').click(); cy.get('main').contains(mySharedReadonlyProject.name).rightclick(); cy.get('[data-cy=context-menu]').within(() => { - cy.contains('Share').click(); + cy.contains('Share').click({ waitForAnimations: false }); }); cy.get('.sharing-dialog').as('sharingDialog'); cy.get('[data-cy=invite-people-field]').find('input').type(activeUser.user.email); cy.get('[role=tooltip]').click(); cy.get('@sharingDialog').within(() => { cy.get('[data-cy=add-invited-people]').click(); - cy.contains('Close').click(); + cy.contains('Close').click({ waitForAnimations: false }); }); }); @@ -117,7 +117,7 @@ describe('Sharing tests', function () { // Test move to trash cy.get('main').contains(mySharedWritableProject.name).rightclick(); cy.get('[data-cy=context-menu]').should('contain', 'Move to trash'); - cy.get('[data-cy=context-menu]').contains('Move to trash').click(); + cy.get('[data-cy=context-menu]').contains('Move to trash').click({ waitForAnimations: false }); // GUARD: Let's wait for the above removed project to disappear // before continuing, to avoid intermittent failures. @@ -161,7 +161,7 @@ describe('Sharing tests', function () { .then(function ([]) { cy.loginAs(adminUser); cy.get('[data-cy=project-panel]').contains(collName).rightclick(); - cy.get('[data-cy=context-menu]').contains('Share').click(); + cy.get('[data-cy=context-menu]').contains('Share').click({ waitForAnimations: false }); cy.get('button').get('[data-cy=add-invited-people]').should('be.disabled'); cy.get('[data-cy=invite-people-field] input').type('Anonymous'); cy.get('div[role=tooltip]').contains('anonymous').click(); diff --git a/services/workbench2/cypress/e2e/workflow.cy.js b/services/workbench2/cypress/e2e/workflow.cy.js index b9cf86c556..b17ddf980a 100644 --- a/services/workbench2/cypress/e2e/workflow.cy.js +++ b/services/workbench2/cypress/e2e/workflow.cy.js @@ -242,10 +242,35 @@ describe('Registered workflow panel tests', function() { cy.goToPath(`/projects/${activeUser.user.uuid}`); cy.get('[data-cy=project-panel] table tbody').contains(workflowResource.name).rightclick(); cy.get('[data-cy=context-menu]').contains('Delete Workflow').click(); + cy.get('[data-cy=confirmation-dialog-ok-btn]').should('exist').click(); cy.get('[data-cy=project-panel] table tbody').should('not.contain', workflowResource.name); }); }); + it('can delete multiple workflows', function() { + const wfNames = ["Test wf1", "Test wf2", "Test wf3"]; + + wfNames.forEach((wfName) => { + cy.createResource(activeUser.token, "workflows", {workflow: {name: wfName}}) + }); + + cy.loginAs(activeUser); + + wfNames.forEach((wfName) => { + cy.get('tr').contains('td', wfName).should('exist').parent('tr').find('input[type="checkbox"]').click(); + }); + + cy.waitForDom().get('[data-cy=multiselect-button]', {timeout: 10000}).should('be.visible') + cy.get('[data-cy=multiselect-button]', {timeout: 10000}).should('have.length', '1').trigger('mouseover'); + cy.get('body').contains('Delete Workflow', {timeout: 10000}).should('exist') + cy.get('[data-cy=multiselect-button]').eq(0).click(); + cy.get('[data-cy=confirmation-dialog-ok-btn]').should('exist').click(); + + wfNames.forEach((wfName) => { + cy.get('tr').contains(wfName).should('not.exist'); + }); + }); + it('cannot delete readonly workflow', function() { cy.createProject({ owningUser: adminUser, diff --git a/services/workbench2/package.json b/services/workbench2/package.json index 94e35029c4..8ae2d8a3e9 100644 --- a/services/workbench2/package.json +++ b/services/workbench2/package.json @@ -28,9 +28,9 @@ "@types/react-window": "1.8.2", "@types/redux-form": "7.4.12", "@types/shell-escape": "^0.2.0", - "axios": "^0.21.1", + "axios": "^0.28.1", "bootstrap": "^5.3.2", - "caniuse-lite": "1.0.30001606", + "caniuse-lite": "1.0.30001612", "classnames": "2.2.6", "cwlts": "1.15.29", "date-fns": "^2.28.0", @@ -68,7 +68,7 @@ "react-router-dom": "4.3.1", "react-router-redux": "5.0.0-alpha.9", "react-rte": "^0.16.5", - "react-scripts": "3.4.4", + "react-scripts": "4.0.1", "react-splitter-layout": "3.0.1", "react-transition-group": "2.5.0", "react-virtualized-auto-sizer": "1.0.2", @@ -93,8 +93,8 @@ "test-local": "react-scripts test", "eject": "react-scripts eject", "lint": "tslint src/** -t verbose", - "build-css": "node-sass-chokidar src/ -o src/", - "watch-css": "npm run build-css && node-sass-chokidar src/ -o src/ --watch --recursive" + "build-css": "node-sass src/ -o src/", + "watch-css": "npm run build-css && node-sass src/ -o src/ --watch --recursive" }, "devDependencies": { "@sinonjs/fake-timers": "^10.3.0", @@ -120,7 +120,6 @@ "enzyme-adapter-react-16": "1.15.6", "jest-localstorage-mock": "2.2.0", "node-sass": "^9.0.0", - "node-sass-chokidar": "^2.0.0", "redux-devtools": "3.4.1", "redux-mock-store": "1.5.4", "ts-mock-imports": "1.3.7", @@ -142,5 +141,11 @@ "last 1 safari version" ] }, - "packageManager": "yarn@3.2.0" + "packageManager": "yarn@3.2.0", + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + } } diff --git a/services/workbench2/src/components/collection-panel-files/collection-panel-files.tsx b/services/workbench2/src/components/collection-panel-files/collection-panel-files.tsx index e58eb89198..03d4551cab 100644 --- a/services/workbench2/src/components/collection-panel-files/collection-panel-files.tsx +++ b/services/workbench2/src/components/collection-panel-files/collection-panel-files.tsx @@ -326,14 +326,16 @@ export const CollectionPanelFiles = withStyles(styles)( setLeftSearch(""); setRightSearch(""); } - }, [rightKey, rightData]); // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [rightKey, rightData]); const currentPDH = (collectionPanel.item || {}).portableDataHash; React.useEffect(() => { if (currentPDH) { fetchData([leftKey, rightKey], true); } - }, [currentPDH]); // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [currentPDH]); React.useEffect(() => { if (rightData) { @@ -451,7 +453,8 @@ export const CollectionPanelFiles = withStyles(styles)( onItemMenuOpen(event, item, isWritable); } }, - [path, setPath, collectionPanelFiles] // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + [path, setPath, collectionPanelFiles] ); const getItemIcon = React.useCallback( @@ -487,7 +490,8 @@ export const CollectionPanelFiles = withStyles(styles)( (ev, isWritable) => { props.onOptionsMenuOpen(ev, isWritable); }, - [props.onOptionsMenuOpen] // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + [props.onOptionsMenuOpen] ); return ( diff --git a/services/workbench2/src/components/conditional-tabs/conditional-tabs.test.tsx b/services/workbench2/src/components/conditional-tabs/conditional-tabs.test.tsx new file mode 100644 index 0000000000..db30135b2e --- /dev/null +++ b/services/workbench2/src/components/conditional-tabs/conditional-tabs.test.tsx @@ -0,0 +1,106 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import React from "react"; +import { mount, configure } from "enzyme"; +import { ConditionalTabs, TabData } from "./conditional-tabs"; +import Adapter from 'enzyme-adapter-react-16'; +import { Tab } from "@material-ui/core"; + +configure({ adapter: new Adapter() }); + +describe("", () => { + let tabs: TabData[] = []; + + beforeEach(() => { + tabs = [{ + show: true, + label: "Tab1", + content:
Content1
, + },{ + show: false, + label: "Tab2", + content:
Content2
, + },{ + show: true, + label: "Tab3", + content:
Content3
, + }]; + }); + + it("renders only visible tabs", () => { + // given + const tabContainer = mount(); + + // expect 2 visible tabs + expect(tabContainer.find(Tab)).toHaveLength(2); + expect(tabContainer.find(Tab).at(0).text()).toBe("Tab1"); + expect(tabContainer.find(Tab).at(1).text()).toBe("Tab3"); + // expect visible content 1 and tab 3 to be hidden but exist + // content 2 stays unrendered since the tab is hidden + expect(tabContainer.find('div#content1').text()).toBe("Content1"); + expect(tabContainer.find('div#content1').prop('hidden')).toBeFalsy(); + expect(tabContainer.find('div#content2').exists()).toBeFalsy(); + expect(tabContainer.find('div#content3').prop('hidden')).toBeTruthy(); + + // Show second tab + tabs[1].show = true; + tabContainer.setProps({ tabs: tabs }); + tabContainer.update(); + + // Expect 3 visible tabs + expect(tabContainer.find(Tab)).toHaveLength(3); + expect(tabContainer.find(Tab).at(0).text()).toBe("Tab1"); + expect(tabContainer.find(Tab).at(1).text()).toBe("Tab2"); + expect(tabContainer.find(Tab).at(2).text()).toBe("Tab3"); + // Expect visible content 1 and hidden content 2/3 + expect(tabContainer.find('div#content1').text()).toBe("Content1"); + expect(tabContainer.find('div#content1').prop('hidden')).toBeFalsy(); + expect(tabContainer.find('div#content2').prop('hidden')).toBeTruthy(); + expect(tabContainer.find('div#content3').prop('hidden')).toBeTruthy(); + + // Click on Tab2 (position 1) + tabContainer.find(Tab).at(1).simulate('click'); + + // Expect 3 visible tabs + expect(tabContainer.find(Tab)).toHaveLength(3); + expect(tabContainer.find(Tab).at(0).text()).toBe("Tab1"); + expect(tabContainer.find(Tab).at(1).text()).toBe("Tab2"); + expect(tabContainer.find(Tab).at(2).text()).toBe("Tab3"); + // Expect visible content2 and hidden content 1/3 + expect(tabContainer.find('div#content2').text()).toBe("Content2"); + expect(tabContainer.find('div#content1').prop('hidden')).toBeTruthy(); + expect(tabContainer.find('div#content2').prop('hidden')).toBeFalsy(); + expect(tabContainer.find('div#content3').prop('hidden')).toBeTruthy(); + }); + + it("resets selected tab on tab visibility change", () => { + // given + const tabContainer = mount(); + + // Expect second tab to be Tab3 + expect(tabContainer.find(Tab).at(1).text()).toBe("Tab3"); + // Click on Tab3 (position 2) + tabContainer.find(Tab).at(1).simulate('click'); + expect(tabContainer.find('div#content3').text()).toBe("Content3"); + expect(tabContainer.find('div#content1').prop('hidden')).toBeTruthy(); + expect(tabContainer.find('div#content2').exists()).toBeFalsy(); + expect(tabContainer.find('div#content3').prop('hidden')).toBeFalsy(); + + // when Tab2 becomes visible + tabs[1].show = true; + tabContainer.setProps({ tabs: tabs }); + tabContainer.update(); // Needed or else tab1 content will still be hidden + + // Selected tab resets to 1, tabs 2/3 are hidden + expect(tabContainer.find('div#content1').text()).toBe("Content1"); + expect(tabContainer.find('div#content1').prop('hidden')).toBeFalsy(); + expect(tabContainer.find('div#content2').prop('hidden')).toBeTruthy(); + expect(tabContainer.find('div#content3').prop('hidden')).toBeTruthy(); + }); +}); diff --git a/services/workbench2/src/components/conditional-tabs/conditional-tabs.tsx b/services/workbench2/src/components/conditional-tabs/conditional-tabs.tsx new file mode 100644 index 0000000000..248c9c0551 --- /dev/null +++ b/services/workbench2/src/components/conditional-tabs/conditional-tabs.tsx @@ -0,0 +1,50 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import React, { ReactElement, useEffect, useState } from "react"; +import { Tabs, Tab } from "@material-ui/core"; +import { TabsProps } from "@material-ui/core/Tabs"; + +interface ComponentWithHidden { + hidden: boolean; +}; + +export type TabData = { + show: boolean; + label: string; + content: ReactElement; +}; + +type ConditionalTabsProps = { + tabs: TabData[]; +}; + +export const ConditionalTabs = (props: Omit & ConditionalTabsProps) => { + const [tabState, setTabState] = useState(0); + const visibleTabs = props.tabs.filter(tab => tab.show); + const visibleTabNames = visibleTabs.map(tab => tab.label).join(); + + const handleTabChange = (event: React.MouseEvent, value: number) => { + setTabState(value); + }; + + // Reset tab to 0 when tab visibility changes + // (or if tab set change causes visible set to change) + useEffect(() => { + setTabState(0); + }, [visibleTabNames]); + + return <> + + {visibleTabs.map(tab => )} + + + {visibleTabs.map((tab, i) => ( + React.cloneElement(tab.content, {key: i, hidden: i !== tabState}) + ))} + ; +}; diff --git a/services/workbench2/src/components/data-table-filters/data-table-filters-popover.tsx b/services/workbench2/src/components/data-table-filters/data-table-filters-popover.tsx index 557abd825a..a5ac7421c0 100644 --- a/services/workbench2/src/components/data-table-filters/data-table-filters-popover.tsx +++ b/services/workbench2/src/components/data-table-filters/data-table-filters-popover.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0 -import React, { useEffect } from 'react'; +import React from 'react'; import { WithStyles, withStyles, @@ -101,6 +101,10 @@ export const DataTableFiltersPopover = withStyles(styles)( }; icon = React.createRef(); + componentWillUnmount(): void { + this.submit.cancel(); + } + render() { const { name, classes, defaultSelection = SelectionMode.ALL, children } = this.props; const isActive = getNodeDescendants('')(this.state.filters).some((f) => (defaultSelection === SelectionMode.ALL ? !f.selected : f.selected)); @@ -137,7 +141,6 @@ export const DataTableFiltersPopover = withStyles(styles)( - ); } @@ -172,15 +175,6 @@ export const DataTableFiltersPopover = withStyles(styles)( } }, 1000); - MountHandler = () => { - useEffect(() => { - return () => { - this.submit.cancel(); - }; - }, []); - return null; - }; - close = () => { this.setState((prev) => ({ ...prev, diff --git a/services/workbench2/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx b/services/workbench2/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx index 0248c8267d..ced5c89983 100644 --- a/services/workbench2/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx +++ b/services/workbench2/src/components/data-table-multiselect-popover/data-table-multiselect-popover.tsx @@ -84,7 +84,8 @@ export const DataTableMultiselectPopover = withStyles(styles)( <> (
{ diff --git a/services/workbench2/src/components/data-table/data-table.tsx b/services/workbench2/src/components/data-table/data-table.tsx index 7b78799457..89a2e2a8e6 100644 --- a/services/workbench2/src/components/data-table/data-table.tsx +++ b/services/workbench2/src/components/data-table/data-table.tsx @@ -354,7 +354,7 @@ export const DataTable = withStyles(styles)( key={key || index} className={classes.checkBoxCell}>
- + ( ) +//https://pictogrammers.com/library/mdi/icon/delete-forever/ +export const DeleteForever: IconType = (props: any) => ( + + + +) + export type IconType = React.SFC<{ className?: string; style?: object }>; export const AddIcon: IconType = props => ; diff --git a/services/workbench2/src/components/multiselect-toolbar/ms-menu-actions.ts b/services/workbench2/src/components/multiselect-toolbar/ms-menu-actions.ts new file mode 100644 index 0000000000..18ca94662b --- /dev/null +++ b/services/workbench2/src/components/multiselect-toolbar/ms-menu-actions.ts @@ -0,0 +1,28 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +export enum MultiSelectMenuActionNames { + ADD_TO_FAVORITES = 'Add to Favorites', + MOVE_TO_TRASH = 'Move to trash', + ADD_TO_PUBLIC_FAVORITES = 'Add to public favorites', + API_DETAILS = 'API Details', + CANCEL = 'CANCEL', + COPY_AND_RERUN_PROCESS = 'Copy and re-run process', + COPY_TO_CLIPBOARD = 'Copy to clipboard', + DELETE_WORKFLOW = 'Delete Workflow', + EDIT_COLLECTION = 'Edit collection', + EDIT_PROJECT = 'Edit project', + EDIT_PROCESS = 'Edit process', + FREEZE_PROJECT = 'Freeze Project', + MAKE_A_COPY = 'Make a copy', + MOVE_TO = 'Move to', + NEW_PROJECT = 'New project', + OPEN_IN_NEW_TAB = 'Open in new tab', + OPEN_W_3RD_PARTY_CLIENT = 'Open with 3rd party client', + OUTPUTS = 'Outputs', + REMOVE = 'Remove', + RUN_WORKFLOW = 'Run Workflow', + SHARE = 'Share', + VIEW_DETAILS = 'View details', +}; diff --git a/services/workbench2/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts b/services/workbench2/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts index 2b30525e56..5a98d4df77 100644 --- a/services/workbench2/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts +++ b/services/workbench2/src/components/multiselect-toolbar/ms-toolbar-action-filters.ts @@ -65,4 +65,5 @@ export const multiselectActionsFilters: TMultiselectActionsFilters = { [WORKFLOW]: [msWorkflowActionSet, msWorkflowActionFilter], [READONLY_WORKFLOW]: [msWorkflowActionSet, msReadOnlyWorkflowActionFilter], + [ResourceKind.WORKFLOW]: [msWorkflowActionSet, msWorkflowActionFilter], }; diff --git a/services/workbench2/src/components/search-input/search-input.test.tsx b/services/workbench2/src/components/search-input/search-input.test.tsx index ba70f752b9..213b46404b 100644 --- a/services/workbench2/src/components/search-input/search-input.test.tsx +++ b/services/workbench2/src/components/search-input/search-input.test.tsx @@ -11,11 +11,10 @@ configure({ adapter: new Adapter() }); describe("", () => { - jest.useFakeTimers(); - let onSearch: () => void; beforeEach(() => { + jest.useFakeTimers(); onSearch = jest.fn(); }); diff --git a/services/workbench2/src/components/search-input/search-input.tsx b/services/workbench2/src/components/search-input/search-input.tsx index 6d98aed28e..4ae3ea9ef6 100644 --- a/services/workbench2/src/components/search-input/search-input.tsx +++ b/services/workbench2/src/components/search-input/search-input.tsx @@ -46,7 +46,8 @@ export const SearchInput = (props: SearchInputProps) => { setValue(""); clearTimeout(timeout); }; - }, [props.value, props.label]); // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.value, props.label]); useEffect(() => { if (selfClearProp !== props.selfClearProp) { @@ -54,7 +55,8 @@ export const SearchInput = (props: SearchInputProps) => { setSelfClearProp(props.selfClearProp); handleChange({ target: { value: "" } } as any); } - }, [props.selfClearProp]); // eslint-disable-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.selfClearProp]); const handleSubmit = (event: React.FormEvent) => { event.preventDefault(); diff --git a/services/workbench2/src/components/workflow-inputs-form/validators.ts b/services/workbench2/src/components/workflow-inputs-form/validators.ts index 1de21d9f35..7c90c049de 100644 --- a/services/workbench2/src/components/workflow-inputs-form/validators.ts +++ b/services/workbench2/src/components/workflow-inputs-form/validators.ts @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import { CommandInputParameter } from 'models/workflow'; -import { require } from 'validators/require'; +import { fieldRequire } from 'validators/require'; import { CWLType } from '../../models/workflow'; @@ -17,5 +17,5 @@ export const required = ({ type }: CommandInputParameter) => { } } } - return require; + return fieldRequire; }; diff --git a/services/workbench2/src/services/collection-service/collection-service-files-response.test.ts b/services/workbench2/src/services/collection-service/collection-service-files-response.test.ts index a043b7c680..aea95b925f 100644 --- a/services/workbench2/src/services/collection-service/collection-service-files-response.test.ts +++ b/services/workbench2/src/services/collection-service/collection-service-files-response.test.ts @@ -20,8 +20,7 @@ describe('collection-service-files-response', () => { testCases.forEach(([inputURL, inputDisplayName, expectedURL, expectedName]) => { // given const collUUID = 'xxxxx-zzzzz-vvvvvvvvvvvvvvv'; - const xmlData = ` - + const xmlData = ` /c=xxxxx-zzzzz-vvvvvvvvvvvvvvv/ diff --git a/services/workbench2/src/services/collection-service/collection-service.ts b/services/workbench2/src/services/collection-service/collection-service.ts index e50e5ed350..12d31d1678 100644 --- a/services/workbench2/src/services/collection-service/collection-service.ts +++ b/services/workbench2/src/services/collection-service/collection-service.ts @@ -3,7 +3,7 @@ // SPDX-License-Identifier: AGPL-3.0 import { CollectionResource, defaultCollectionSelectedFields } from "models/collection"; -import { AxiosInstance } from "axios"; +import { AxiosInstance, AxiosResponse } from "axios"; import { CollectionFile, CollectionDirectory } from "models/collection-file"; import { WebDAV } from "common/webdav"; import { AuthService } from "../auth-service/auth-service"; @@ -20,6 +20,11 @@ type CollectionPartialUpdateOrCreate = | (Partial & Pick) | (Partial & Pick); +type ReplaceFilesPayload = { + collection: Partial; + replace_files: {[key: string]: string}; +} + export const emptyCollectionPdh = "d41d8cd98f00b204e9800998ecf8427e+0"; export const SOURCE_DESTINATION_EQUAL_ERROR_MESSAGE = "Source and destination cannot be the same"; @@ -78,7 +83,7 @@ export class CollectionService extends TrashableResourceService(`/${this.resourceType}/${data.uuid}`, payload), + this.serverApi.put>(`/${this.resourceType}/${data.uuid}`, payload), this.actions, true, // mapKeys showErrors ); } else { return CommonService.defaultResponse( - this.serverApi.post(`/${this.resourceType}`, payload), + this.serverApi.post>(`/${this.resourceType}`, payload), this.actions, true, // mapKeys showErrors diff --git a/services/workbench2/src/services/services.ts b/services/workbench2/src/services/services.ts index 48cd931127..12938e82d6 100644 --- a/services/workbench2/src/services/services.ts +++ b/services/workbench2/src/services/services.ts @@ -44,7 +44,8 @@ export function setAuthorizationHeader(services: ServiceRepository, token: strin } export function removeAuthorizationHeader(services: ServiceRepository) { - delete services.apiClient.defaults.headers.common; + services.apiClient.defaults.headers.common = {}; + services.keepWebdavClient.setAuthorization(undefined); services.apiWebdavClient.setAuthorization(undefined); } diff --git a/services/workbench2/src/store/auth/auth-middleware.test.ts b/services/workbench2/src/store/auth/auth-middleware.test.ts index 5a0364ebf9..259478fdc4 100644 --- a/services/workbench2/src/store/auth/auth-middleware.test.ts +++ b/services/workbench2/src/store/auth/auth-middleware.test.ts @@ -33,7 +33,9 @@ describe("AuthMiddleware", () => { it("handles LOGOUT action", () => { localStorage.setItem(API_TOKEN_KEY, 'someToken'); - window.location.assign = jest.fn(); + Object.defineProperty(window, 'location', { + value: { assign: jest.fn(), href: 'http://localhost', protocol: 'http:', host: 'localhost'} + }); const next = jest.fn(); const middleware = authMiddleware(services)(store)(next); middleware(authActions.LOGOUT({deleteLinkData: false, preservePath: false})); diff --git a/services/workbench2/src/store/banner/banner-action.ts b/services/workbench2/src/store/banner/banner-action.ts index 808ca822c0..6dcd6c3aa5 100644 --- a/services/workbench2/src/store/banner/banner-action.ts +++ b/services/workbench2/src/store/banner/banner-action.ts @@ -23,7 +23,9 @@ export const closeBanner = () => dispatch(bannerReducerActions.CLOSE_BANNER()); }; -export default { +const bannerActions = { openBanner, closeBanner }; + +export default bannerActions; \ No newline at end of file diff --git a/services/workbench2/src/store/workflow-panel/workflow-panel-actions.ts b/services/workbench2/src/store/workflow-panel/workflow-panel-actions.ts index 37b96bd9b0..ecb0c96b73 100644 --- a/services/workbench2/src/store/workflow-panel/workflow-panel-actions.ts +++ b/services/workbench2/src/store/workflow-panel/workflow-panel-actions.ts @@ -24,6 +24,12 @@ import { getResource } from 'store/resources/resources'; import { ProjectResource } from 'models/project'; import { UserResource } from 'models/user'; import { getWorkflowInputs, parseWorkflowDefinition } from 'models/workflow'; +import { ContextMenuResource } from 'store/context-menu/context-menu-actions'; +import { dialogActions } from 'store/dialog/dialog-actions'; +import { ResourceKind, Resource } from 'models/resource'; +import { selectedToArray } from "components/multiselect-toolbar/MultiselectToolbar"; +import { CommonResourceServiceError, getCommonResourceServiceError } from "services/common-service/common-resource-service"; +import { projectPanelActions } from "store/project-panel/project-panel-action-bind"; export const WORKFLOW_PANEL_ID = "workflowPanel"; const UUID_PREFIX_PROPERTY_NAME = 'uuidPrefix'; @@ -120,10 +126,57 @@ export const getWorkflowDetails = (state: RootState) => { return workflow || undefined; }; -export const deleteWorkflow = (workflowUuid: string, ownerUuid: string) => - async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { - dispatch(navigateTo(ownerUuid)); - dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removing ...', kind: SnackbarKind.INFO })); - await services.workflowService.delete(workflowUuid); - dispatch(snackbarActions.OPEN_SNACKBAR({ message: 'Removed.', hideDuration: 2000, kind: SnackbarKind.SUCCESS })); - }; +export const openRemoveWorkflowDialog = +(resource: ContextMenuResource, numOfWorkflows: Number) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const confirmationText = + numOfWorkflows === 1 + ? "Are you sure you want to remove this workflow?" + : `Are you sure you want to remove these ${numOfWorkflows} workflows?`; + const titleText = numOfWorkflows === 1 ? "Remove workflow permanently" : "Remove workflows permanently"; + + dispatch( + dialogActions.OPEN_DIALOG({ + id: REMOVE_WORKFLOW_DIALOG, + data: { + title: titleText, + text: confirmationText, + confirmButtonLabel: "Remove", + uuid: resource.uuid, + resource, + }, + }) + ); +}; + +export const REMOVE_WORKFLOW_DIALOG = "removeWorkflowDialog"; + +export const removeWorkflowPermanently = (uuid: string, ownerUuid?: string) => async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const resource = getState().dialog.removeWorkflowDialog.data.resource; + const checkedList = getState().multiselect.checkedList; + + const uuidsToRemove: string[] = resource.fromContextMenu ? [resource.uuid] : selectedToArray(checkedList); + + //if no items in checkedlist, default to normal context menu behavior + if (!uuidsToRemove.length) uuidsToRemove.push(uuid); + if(ownerUuid) dispatch(navigateTo(ownerUuid)); + + const workflowsToRemove = uuidsToRemove + .map(uuid => getResource(uuid)(getState().resources) as Resource) + .filter(resource => resource.kind === ResourceKind.WORKFLOW); + + for (const workflow of workflowsToRemove) { + try { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Removing ...", kind: SnackbarKind.INFO })); + await services.workflowService.delete(workflow.uuid); + dispatch(projectPanelActions.REQUEST_ITEMS()); + dispatch(snackbarActions.OPEN_SNACKBAR({ message: "Removed.", hideDuration: 2000, kind: SnackbarKind.SUCCESS })); + } catch (e) { + const error = getCommonResourceServiceError(e); + if (error === CommonResourceServiceError.PERMISSION_ERROR_FORBIDDEN) { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: `Access denied`, hideDuration: 2000, kind: SnackbarKind.ERROR })); + } else { + dispatch(snackbarActions.OPEN_SNACKBAR({ message: `Deletion failed`, hideDuration: 2000, kind: SnackbarKind.ERROR })); + } + } + } +}; \ No newline at end of file diff --git a/services/workbench2/src/validators/require.tsx b/services/workbench2/src/validators/require.tsx index fbba02aeb4..b594bf0803 100644 --- a/services/workbench2/src/validators/require.tsx +++ b/services/workbench2/src/validators/require.tsx @@ -4,6 +4,6 @@ export const ERROR_MESSAGE = 'This field is required.'; -export const require: any = (value: string) => { +export const fieldRequire: any = (value: string) => { return value && value.length > 0 ? undefined : ERROR_MESSAGE; }; diff --git a/services/workbench2/src/validators/validators.tsx b/services/workbench2/src/validators/validators.tsx index 87a4c1f57e..73bc4460dc 100644 --- a/services/workbench2/src/validators/validators.tsx +++ b/services/workbench2/src/validators/validators.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { require } from './require'; +import { fieldRequire } from './require'; import { maxLength } from './max-length'; import { isRsaKey } from './is-rsa-key'; import { isRemoteHost } from "./is-remote-host"; @@ -11,35 +11,35 @@ import { validFilePath, validName, validNameAllowSlash } from "./valid-name"; export const TAG_KEY_VALIDATION = [maxLength(255)]; export const TAG_VALUE_VALIDATION = [maxLength(255)]; -export const PROJECT_NAME_VALIDATION = [require, validName, maxLength(255)]; -export const PROJECT_NAME_VALIDATION_ALLOW_SLASH = [require, validNameAllowSlash, maxLength(255)]; +export const PROJECT_NAME_VALIDATION = [fieldRequire, validName, maxLength(255)]; +export const PROJECT_NAME_VALIDATION_ALLOW_SLASH = [fieldRequire, validNameAllowSlash, maxLength(255)]; -export const COLLECTION_NAME_VALIDATION = [require, validName, maxLength(255)]; -export const COLLECTION_NAME_VALIDATION_ALLOW_SLASH = [require, validNameAllowSlash, maxLength(255)]; +export const COLLECTION_NAME_VALIDATION = [fieldRequire, validName, maxLength(255)]; +export const COLLECTION_NAME_VALIDATION_ALLOW_SLASH = [fieldRequire, validNameAllowSlash, maxLength(255)]; export const COLLECTION_DESCRIPTION_VALIDATION = [maxLength(255)]; -export const COLLECTION_PROJECT_VALIDATION = [require]; +export const COLLECTION_PROJECT_VALIDATION = [fieldRequire]; -export const COPY_NAME_VALIDATION = [require, maxLength(255)]; -export const COPY_FILE_VALIDATION = [require]; -export const RENAME_FILE_VALIDATION = [require, validFilePath]; +export const COPY_NAME_VALIDATION = [fieldRequire, maxLength(255)]; +export const COPY_FILE_VALIDATION = [fieldRequire]; +export const RENAME_FILE_VALIDATION = [fieldRequire, validFilePath]; -export const MOVE_TO_VALIDATION = [require]; +export const MOVE_TO_VALIDATION = [fieldRequire]; -export const PROCESS_NAME_VALIDATION = [require, maxLength(255)]; +export const PROCESS_NAME_VALIDATION = [fieldRequire, maxLength(255)]; export const PROCESS_DESCRIPTION_VALIDATION = [maxLength(255)]; -export const REPOSITORY_NAME_VALIDATION = [require, maxLength(255)]; +export const REPOSITORY_NAME_VALIDATION = [fieldRequire, maxLength(255)]; -export const USER_EMAIL_VALIDATION = [require, maxLength(255)]; +export const USER_EMAIL_VALIDATION = [fieldRequire, maxLength(255)]; export const PROFILE_EMAIL_VALIDATION = [maxLength(255)]; export const PROFILE_URL_VALIDATION = [maxLength(255)]; export const USER_LENGTH_VALIDATION = [maxLength(255)]; -export const SSH_KEY_PUBLIC_VALIDATION = [require, isRsaKey, maxLength(1024)]; -export const SSH_KEY_NAME_VALIDATION = [require, maxLength(255)]; +export const SSH_KEY_PUBLIC_VALIDATION = [fieldRequire, isRsaKey, maxLength(1024)]; +export const SSH_KEY_NAME_VALIDATION = [fieldRequire, maxLength(255)]; -export const SITE_MANAGER_REMOTE_HOST_VALIDATION = [require, isRemoteHost, maxLength(255)]; +export const SITE_MANAGER_REMOTE_HOST_VALIDATION = [fieldRequire, isRemoteHost, maxLength(255)]; -export const MY_ACCOUNT_VALIDATION = [require]; +export const MY_ACCOUNT_VALIDATION = [fieldRequire]; -export const CHOOSE_VM_VALIDATION = [require]; +export const CHOOSE_VM_VALIDATION = [fieldRequire]; diff --git a/services/workbench2/src/views-components/auto-logout/auto-logout.test.tsx b/services/workbench2/src/views-components/auto-logout/auto-logout.test.tsx index c9b9e2b83f..28084ed1c1 100644 --- a/services/workbench2/src/views-components/auto-logout/auto-logout.test.tsx +++ b/services/workbench2/src/views-components/auto-logout/auto-logout.test.tsx @@ -14,15 +14,12 @@ describe('', () => { const sessionIdleTimeout = 300; const lastWarningDuration = 60; const eventListeners = {}; - jest.useFakeTimers(); - beforeAll(() => { + beforeEach(() => { + jest.useFakeTimers(); window.addEventListener = jest.fn((event, cb) => { eventListeners[event] = cb; }); - }); - - beforeEach(() => { props = { sessionIdleTimeout: sessionIdleTimeout, lastWarningDuration: lastWarningDuration, diff --git a/services/workbench2/src/views-components/context-menu/action-sets/workflow-action-set.ts b/services/workbench2/src/views-components/context-menu/action-sets/workflow-action-set.ts index f03340db4b..4e76f2aa4d 100644 --- a/services/workbench2/src/views-components/context-menu/action-sets/workflow-action-set.ts +++ b/services/workbench2/src/views-components/context-menu/action-sets/workflow-action-set.ts @@ -3,8 +3,8 @@ // SPDX-License-Identifier: AGPL-3.0 import { ContextMenuActionSet, ContextMenuActionNames } from "views-components/context-menu/context-menu-action-set"; -import { openRunProcess, deleteWorkflow } from "store/workflow-panel/workflow-panel-actions"; -import { DetailsIcon, AdvancedIcon, OpenIcon, Link, StartIcon, TrashIcon } from "components/icon/icon"; +import { openRunProcess, openRemoveWorkflowDialog } from "store/workflow-panel/workflow-panel-actions"; +import { DetailsIcon, AdvancedIcon, OpenIcon, Link, StartIcon, DeleteForever } from "components/icon/icon"; import { copyToClipboardAction, openInNewTabAction } from "store/open-in-new-tab/open-in-new-tab.actions"; import { toggleDetailsPanel } from "store/details-panel/details-panel-action"; import { openAdvancedTabDialog } from "store/advanced-tab/advanced-tab"; @@ -53,10 +53,10 @@ export const workflowActionSet: ContextMenuActionSet = [ [ ...readOnlyWorkflowActionSet[0], { - icon: TrashIcon, - name: ContextMenuActionNames.DELETE_WORKFLOW, + icon: DeleteForever, + name: "Delete Workflow", execute: (dispatch, resources) => { - dispatch(deleteWorkflow(resources[0].uuid, resources[0].ownerUuid)); + dispatch(openRemoveWorkflowDialog(resources[0], resources.length)); }, }, ], diff --git a/services/workbench2/src/views-components/context-menu/actions/download-action.test.tsx b/services/workbench2/src/views-components/context-menu/actions/download-action.test.tsx index e3fcfd19e4..ed41225a07 100644 --- a/services/workbench2/src/views-components/context-menu/actions/download-action.test.tsx +++ b/services/workbench2/src/views-components/context-menu/actions/download-action.test.tsx @@ -23,8 +23,6 @@ const mock = { generateAsync: jest.fn().mockImplementation(() => Promise.resolve('test')), }; -jest.mock('jszip', () => jest.fn().mockImplementation(() => mock)); - describe('', () => { let props; let zip; diff --git a/services/workbench2/src/views-components/dialog-upload/dialog-collection-files-upload.tsx b/services/workbench2/src/views-components/dialog-upload/dialog-collection-files-upload.tsx index f65bdabfeb..c29b627d36 100644 --- a/services/workbench2/src/views-components/dialog-upload/dialog-collection-files-upload.tsx +++ b/services/workbench2/src/views-components/dialog-upload/dialog-collection-files-upload.tsx @@ -7,7 +7,7 @@ import { InjectedFormProps, Field } from 'redux-form'; import { WithDialogProps } from 'store/dialog/with-dialog'; import { CollectionCreateFormDialogData } from 'store/collections/collection-create-actions'; import { FormDialog } from 'components/form-dialog/form-dialog'; -import { require } from 'validators/require'; +import { fieldRequire } from 'validators/require'; import { FileUploaderField } from 'views-components/file-uploader/file-uploader'; import { WarningCollection } from 'components/warning-collection/warning-collection'; import { fileUploaderActions } from 'store/file-uploader/file-uploader-actions'; @@ -43,6 +43,6 @@ const UploadCollectionFilesFields = () => <> ; -const FILES_FIELD_VALIDATION = [require]; +const FILES_FIELD_VALIDATION = [fieldRequire]; diff --git a/services/workbench2/src/views-components/login-form/login-form.tsx b/services/workbench2/src/views-components/login-form/login-form.tsx index 6c5902653b..7d71078c31 100644 --- a/services/workbench2/src/views-components/login-form/login-form.tsx +++ b/services/workbench2/src/views-components/login-form/login-form.tsx @@ -13,6 +13,7 @@ import { DispatchProp } from 'react-redux'; import { saveApiToken } from 'store/auth/auth-action'; import { navigateToRootProject } from 'store/navigation/navigation-action'; import { replace } from 'react-router-redux'; +import { PasswordLoginResponse } from 'views/login-panel/login-panel'; type CssRules = 'root' | 'loginBtn' | 'card' | 'wrapper' | 'progress'; @@ -46,7 +47,7 @@ const styles: StyleRulesCallback = theme => ({ }); type LoginFormProps = DispatchProp & WithStyles & { - handleSubmit: (username: string, password: string) => AxiosPromise; + handleSubmit: (username: string, password: string) => AxiosPromise; loginLabel?: string, }; diff --git a/services/workbench2/src/views-components/multiselect-toolbar/ms-process-action-set.ts b/services/workbench2/src/views-components/multiselect-toolbar/ms-process-action-set.ts index 73aebe27bc..0637fcc468 100644 --- a/services/workbench2/src/views-components/multiselect-toolbar/ms-process-action-set.ts +++ b/services/workbench2/src/views-components/multiselect-toolbar/ms-process-action-set.ts @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { RemoveIcon, ReRunProcessIcon, OutputIcon, RenameIcon, StopIcon } from "components/icon/icon"; +import { ContextMenuActionNames } from "views-components/context-menu/context-menu-action-set"; +import { DeleteForever, ReRunProcessIcon, OutputIcon, RenameIcon, StopIcon } from "components/icon/icon"; import { openCopyProcessDialog } from "store/processes/process-copy-actions"; import { openRemoveProcessDialog } from "store/processes/processes-actions"; import { MultiSelectMenuAction, MultiSelectMenuActionSet, msCommonActionSet } from "./ms-menu-actions"; -import { ContextMenuActionNames } from "views-components/context-menu/context-menu-action-set"; import { openProcessUpdateDialog } from "store/processes/process-update-actions"; import { msNavigateToOutput } from "store/multiselect/multiselect-actions"; import { cancelRunningWorkflow } from "store/processes/processes-actions"; @@ -25,7 +25,7 @@ const msCopyAndRerunProcess: MultiSelectMenuAction = { const msRemoveProcess: MultiSelectMenuAction = { name: ContextMenuActionNames.REMOVE, - icon: RemoveIcon, + icon: DeleteForever, hasAlts: false, isForMulti: true, execute: (dispatch, resources) => { diff --git a/services/workbench2/src/views-components/multiselect-toolbar/ms-workflow-action-set.ts b/services/workbench2/src/views-components/multiselect-toolbar/ms-workflow-action-set.ts index 9c5cdd79e0..124981aa17 100644 --- a/services/workbench2/src/views-components/multiselect-toolbar/ms-workflow-action-set.ts +++ b/services/workbench2/src/views-components/multiselect-toolbar/ms-workflow-action-set.ts @@ -2,8 +2,8 @@ // // SPDX-License-Identifier: AGPL-3.0 -import { openRunProcess, deleteWorkflow } from 'store/workflow-panel/workflow-panel-actions'; -import { StartIcon, TrashIcon, Link } from 'components/icon/icon'; +import { openRunProcess, openRemoveWorkflowDialog } from 'store/workflow-panel/workflow-panel-actions'; +import { StartIcon, DeleteForever, Link } from 'components/icon/icon'; import { MultiSelectMenuAction, MultiSelectMenuActionSet, msCommonActionSet } from './ms-menu-actions'; import { ContextMenuActionNames } from 'views-components/context-menu/context-menu-action-set'; import { copyToClipboardAction } from 'store/open-in-new-tab/open-in-new-tab.actions'; @@ -24,11 +24,13 @@ const msRunWorkflow: MultiSelectMenuAction = { const msDeleteWorkflow: MultiSelectMenuAction = { name: DELETE_WORKFLOW, - icon: TrashIcon, + icon: DeleteForever, hasAlts: false, - isForMulti: false, + isForMulti: true, execute: (dispatch, resources) => { - dispatch(deleteWorkflow(resources[0].uuid, resources[0].ownerUuid)); + for (const resource of [...resources]){ + dispatch(openRemoveWorkflowDialog(resource, resources.length)); + } }, }; diff --git a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.test.tsx b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.test.tsx index 2fc4d01ad6..86370a1e21 100644 --- a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.test.tsx +++ b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.test.tsx @@ -8,7 +8,8 @@ import Adapter from 'enzyme-adapter-react-16'; import { Provider } from 'react-redux'; import { combineReducers, createStore } from 'redux'; -import SharingDialogComponent, { +import { + SharingDialogComponent, SharingDialogComponentProps, } from './sharing-dialog-component'; import { diff --git a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.tsx b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.tsx index 01082211d3..919dbe76f1 100644 --- a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.tsx +++ b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog-component.tsx @@ -62,7 +62,7 @@ enum SharingDialogTab { } export type SharingDialogComponentProps = SharingDialogDataProps & SharingDialogActionProps; -export default (props: SharingDialogComponentProps) => { +export const SharingDialogComponent = (props: SharingDialogComponentProps) => { const { open, loading, saveEnabled, sharedResourceUuid, sharingURLsNr, privateAccess, sharingURLsDisabled, onClose, onSave, onCreateSharingToken, refreshPermissions } = props; diff --git a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog.tsx b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog.tsx index 1c9e4d0393..b5f2bd74cc 100644 --- a/services/workbench2/src/views-components/sharing-dialog/sharing-dialog.tsx +++ b/services/workbench2/src/views-components/sharing-dialog/sharing-dialog.tsx @@ -15,7 +15,8 @@ import { initializeManagementForm } from 'store/sharing-dialog/sharing-dialog-actions'; import { WithDialogProps } from 'store/dialog/with-dialog'; -import SharingDialogComponent, { +import { + SharingDialogComponent, SharingDialogDataProps, SharingDialogActionProps } from './sharing-dialog-component'; diff --git a/services/workbench2/src/views-components/sharing-dialog/sharing-invitation-form-component.tsx b/services/workbench2/src/views-components/sharing-dialog/sharing-invitation-form-component.tsx index 19fcf58849..cf463fa76a 100644 --- a/services/workbench2/src/views-components/sharing-dialog/sharing-invitation-form-component.tsx +++ b/services/workbench2/src/views-components/sharing-dialog/sharing-invitation-form-component.tsx @@ -4,7 +4,7 @@ import React from 'react'; import { Field, WrappedFieldProps, FieldArray, WrappedFieldArrayProps } from 'redux-form'; -import { Grid, FormControl, InputLabel, StyleRulesCallback, Divider } from '@material-ui/core'; +import { Grid, FormControl, InputLabel, StyleRulesCallback } from '@material-ui/core'; import { PermissionSelect, parsePermissionLevel, formatPermissionLevel } from './permission-select'; import { ParticipantSelect, Participant } from './participant-select'; import { WithStyles } from '@material-ui/core/styles'; diff --git a/services/workbench2/src/views-components/workflow-remove-dialog/workflow-remove-dialog.tsx b/services/workbench2/src/views-components/workflow-remove-dialog/workflow-remove-dialog.tsx new file mode 100644 index 0000000000..d3f4874370 --- /dev/null +++ b/services/workbench2/src/views-components/workflow-remove-dialog/workflow-remove-dialog.tsx @@ -0,0 +1,21 @@ +// Copyright (C) The Arvados Authors. All rights reserved. +// +// SPDX-License-Identifier: AGPL-3.0 + +import { Dispatch, compose } from 'redux'; +import { connect } from "react-redux"; +import { ConfirmationDialog } from "components/confirmation-dialog/confirmation-dialog"; +import { withDialog, WithDialogProps } from "store/dialog/with-dialog"; +import { removeWorkflowPermanently, REMOVE_WORKFLOW_DIALOG } from 'store/workflow-panel/workflow-panel-actions'; + +const mapDispatchToProps = (dispatch: Dispatch, props: WithDialogProps) => ({ + onConfirm: () => { + props.closeDialog(); + dispatch(removeWorkflowPermanently(props.data.uuid)); + } +}); + +export const RemoveWorkflowDialog = compose( + withDialog(REMOVE_WORKFLOW_DIALOG), + connect(null, mapDispatchToProps) +)(ConfirmationDialog); diff --git a/services/workbench2/src/views/login-panel/login-panel.tsx b/services/workbench2/src/views/login-panel/login-panel.tsx index f834b3b6df..452a66672a 100644 --- a/services/workbench2/src/views/login-panel/login-panel.tsx +++ b/services/workbench2/src/views/login-panel/login-panel.tsx @@ -10,7 +10,7 @@ import { login, authActions } from 'store/auth/auth-action'; import { ArvadosTheme } from 'common/custom-theme'; import { RootState } from 'store/store'; import { LoginForm } from 'views-components/login-form/login-form'; -import Axios from 'axios'; +import Axios, { AxiosResponse } from 'axios'; import { Config } from 'common/config'; import { sanitizeHTML } from 'common/html-sanitize'; @@ -51,11 +51,17 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ } }); +export type PasswordLoginResponse = { + uuid?: string; + api_token?: string; + message?: string; +}; + const doPasswordLogin = (url: string) => (username: string, password: string) => { const formData: string[] = []; formData.push('username='+encodeURIComponent(username)); formData.push('password='+encodeURIComponent(password)); - return Axios.post(`${url}/arvados/v1/users/authenticate`, formData.join('&'), { + return Axios.post>(`${url}/arvados/v1/users/authenticate`, formData.join('&'), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, diff --git a/services/workbench2/src/views/process-panel/process-io-card.test.tsx b/services/workbench2/src/views/process-panel/process-io-card.test.tsx index c0feead398..38061e3f06 100644 --- a/services/workbench2/src/views/process-panel/process-io-card.test.tsx +++ b/services/workbench2/src/views/process-panel/process-io-card.test.tsx @@ -138,6 +138,36 @@ describe('renderers', () => { expect(panel.find(TableBody).text()).toContain('someValue'); }); + it('shows main process with output collection', () => { + // when + const outputCollection = '987654321'; + const parameters = [{id: 'someId', label: 'someLabel', value: {display: 'someValue'}}]; + let panel = mount( + + + + + + ); + + // then + expect(panel.find(CircularProgress).exists()).toBeFalsy(); + expect(panel.find(Tab).length).toBe(3); // Empty raw is shown if parameters are present + expect(panel.find(TableBody).text()).toContain('someId'); + expect(panel.find(TableBody).text()).toContain('someLabel'); + expect(panel.find(TableBody).text()).toContain('someValue'); + + // Visit output tab + panel.find(Tab).at(2).simulate('click'); + expect(panel.find(ProcessOutputCollectionFiles).prop('currentItemUuid')).toBe(outputCollection); + }); + // Subprocess it('shows subprocess loading', () => { diff --git a/services/workbench2/src/views/process-panel/process-io-card.tsx b/services/workbench2/src/views/process-panel/process-io-card.tsx index 5851b145d4..6d60b8cf22 100644 --- a/services/workbench2/src/views/process-panel/process-io-card.tsx +++ b/services/workbench2/src/views/process-panel/process-io-card.tsx @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: AGPL-3.0 -import React, { ReactElement, memo, useState } from "react"; +import React, { ReactElement, memo } from "react"; import { Dispatch } from "redux"; import { StyleRulesCallback, @@ -14,8 +14,6 @@ import { CardContent, Tooltip, Typography, - Tabs, - Tab, Table, TableHead, TableBody, @@ -70,6 +68,7 @@ import { KEEP_URL_REGEX } from "models/resource"; import { FixedSizeList } from 'react-window'; import AutoSizer from "react-virtualized-auto-sizer"; import { LinkProps } from "@material-ui/core/Link"; +import { ConditionalTabs } from "components/conditional-tabs/conditional-tabs"; type CssRules = | "card" @@ -123,7 +122,7 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ color: theme.customs.colors.greyD, fontSize: "1.875rem", }, - // Applies to table tab's content + // Applies to table tab and collection table content tableWrapper: { height: "auto", maxHeight: `calc(100% - ${theme.spacing.unit * 6}px)`, @@ -131,7 +130,8 @@ const styles: StyleRulesCallback = (theme: ArvadosTheme) => ({ // Use flexbox to keep scrolling at the virtual list level display: "flex", flexDirection: "column", - alignItems: "start", // Prevents scroll bars at different levels in json tab + alignItems: "stretch", // Stretches output collection to full width + }, // Param table virtual list styles @@ -267,272 +267,206 @@ export interface ProcessIOCardDataProps { forceShowParams?: boolean; } -export interface ProcessIOCardActionProps { - navigateTo: (uuid: string) => void; -} - -const mapDispatchToProps = (dispatch: Dispatch): ProcessIOCardActionProps => ({ - navigateTo: uuid => dispatch(navigateTo(uuid)), -}); - -type ProcessIOCardProps = ProcessIOCardDataProps & ProcessIOCardActionProps & WithStyles & MPVPanelProps; +type ProcessIOCardProps = ProcessIOCardDataProps & WithStyles & MPVPanelProps; export const ProcessIOCard = withStyles(styles)( - connect( - null, - mapDispatchToProps - )( - ({ - classes, - label, - params, - raw, - mounts, - outputUuid, - doHidePanel, - doMaximizePanel, - doUnMaximizePanel, - panelMaximized, - panelName, - process, - navigateTo, - forceShowParams, - }: ProcessIOCardProps) => { - const [mainProcTabState, setMainProcTabState] = useState(0); - const [subProcTabState, setSubProcTabState] = useState(0); - const handleMainProcTabChange = (event: React.MouseEvent, value: number) => { - setMainProcTabState(value); - }; - const handleSubProcTabChange = (event: React.MouseEvent, value: number) => { - setSubProcTabState(value); - }; - - const PanelIcon = label === ProcessIOCardType.INPUT ? InputIcon : OutputIcon; - const mainProcess = !(process && process!.containerRequest.requestingContainerUuid); - const showParamTable = mainProcess || forceShowParams; - - const loading = raw === null || raw === undefined || params === null; + ({ + classes, + label, + params, + raw, + mounts, + outputUuid, + doHidePanel, + doMaximizePanel, + doUnMaximizePanel, + panelMaximized, + panelName, + process, + forceShowParams, + }: ProcessIOCardProps) => { + const PanelIcon = label === ProcessIOCardType.INPUT ? InputIcon : OutputIcon; + const mainProcess = !(process && process!.containerRequest.requestingContainerUuid); + const showParamTable = mainProcess || forceShowParams; + + const loading = raw === null || raw === undefined || params === null; + + const hasRaw = !!(raw && Object.keys(raw).length > 0); + const hasParams = !!(params && params.length > 0); + // isRawLoaded allows subprocess panel to display raw even if it's {} + const isRawLoaded = !!(raw && Object.keys(raw).length >= 0); + + // Subprocess + const hasInputMounts = !!(label === ProcessIOCardType.INPUT && mounts && mounts.length); + const hasOutputCollecton = !!(label === ProcessIOCardType.OUTPUT && outputUuid); + // Subprocess should not show loading if hasOutputCollection or hasInputMounts + const subProcessLoading = loading && !hasOutputCollecton && !hasInputMounts; - const hasRaw = !!(raw && Object.keys(raw).length > 0); - const hasParams = !!(params && params.length > 0); - // isRawLoaded allows subprocess panel to display raw even if it's {} - const isRawLoaded = !!(raw && Object.keys(raw).length >= 0); - - // Subprocess - const hasInputMounts = !!(label === ProcessIOCardType.INPUT && mounts && mounts.length); - const hasOutputCollecton = !!(label === ProcessIOCardType.OUTPUT && outputUuid); - // Subprocess should not show loading if hasOutputCollection or hasInputMounts - const subProcessLoading = loading && !hasOutputCollecton && !hasInputMounts; - - return ( - - } - title={ - - {label} - - } - action={ -
- {doUnMaximizePanel && panelMaximized && ( - - - - - - )} - {doMaximizePanel && !panelMaximized && ( - - - - - - )} - {doHidePanel && ( - - - - - - )} -
- } - /> - - {showParamTable ? ( - <> - {/* raw is undefined until params are loaded */} - {loading && ( - + } + title={ + + {label} + + } + action={ +
+ {doUnMaximizePanel && panelMaximized && ( + + + + + + )} + {doMaximizePanel && !panelMaximized && ( + + + + + + )} + {doHidePanel && ( + + - - - )} - {/* Once loaded, either raw or params may still be empty - * Raw when all params are empty - * Params when raw is provided by containerRequest properties but workflow mount is absent for preview - */} - {!loading && (hasRaw || hasParams) && ( - <> - - {/* params will be empty on processes without workflow definitions in mounts, so we only show raw */} - {hasParams && } - {!forceShowParams && } - {hasOutputCollecton && } - - {mainProcTabState === 0 && params && hasParams && ( -
- + + + )} +
+ } + /> + + {showParamTable ? ( + <> + {/* raw is undefined until params are loaded */} + {loading && ( + + + + )} + {/* Once loaded, either raw or params may still be empty + * Raw when all params are empty + * Params when raw is provided by containerRequest properties but workflow mount is absent for preview + */} + {!loading && (hasRaw || hasParams) && ( + -
- )} - {(mainProcTabState === 1 || !hasParams) && ( -
- -
- )} - {mainProcTabState === 2 && hasOutputCollecton && ( - <> - {outputUuid && ( - - Output Collection:{" "} - { - navigateTo(outputUuid || ""); - }} - > - {outputUuid} - - - )} - - - )} - - - )} - {!loading && !hasRaw && !hasParams && ( - - - - )} - - ) : ( - // Subprocess - <> - {subProcessLoading ? ( - - - - ) : !subProcessLoading && (hasInputMounts || hasOutputCollecton || isRawLoaded) ? ( - <> - - {hasInputMounts && } - {hasOutputCollecton && } - {isRawLoaded && } - -
- {subProcTabState === 0 && hasInputMounts && } - {subProcTabState === 0 && hasOutputCollecton && ( - <> - {outputUuid && ( - - Output Collection:{" "} - { - navigateTo(outputUuid || ""); - }} - > - {outputUuid} - - - )} - - - )} - {isRawLoaded && (subProcTabState === 1 || (!hasInputMounts && !hasOutputCollecton)) && ( -
- -
- )} -
- - ) : ( - - - - )} - - )} -
-
- ); - } - ) + />, + }, + { + show: !forceShowParams, + label: "JSON", + content: , + }, + { + show: hasOutputCollecton, + label: "Collection", + content: , + }, + ]} + /> + )} + {!loading && !hasRaw && !hasParams && ( + + + + )} + + ) : ( + // Subprocess + <> + {subProcessLoading ? ( + + + + ) : !subProcessLoading && (hasInputMounts || hasOutputCollecton || isRawLoaded) ? ( + , + }, + { + show: hasOutputCollecton, + label: "Collection", + content: , + }, + { + show: isRawLoaded, + label: "JSON", + content: , + }, + ]} + /> + ) : ( + + + + )} + + )} + + + ); + } ); export type ProcessIOValue = { @@ -551,12 +485,13 @@ export type ProcessIOParameter = { interface ProcessIOPreviewDataProps { data: ProcessIOParameter[]; valueLabel: string; + hidden?: boolean; } type ProcessIOPreviewProps = ProcessIOPreviewDataProps & WithStyles; const ProcessIOPreview = memo( - withStyles(styles)(({ classes, data, valueLabel }: ProcessIOPreviewProps) => { + withStyles(styles)(({ data, valueLabel, hidden, classes }: ProcessIOPreviewProps) => { const showLabel = data.some((param: ProcessIOParameter) => param.label); const hasMoreValues = (index: number) => ( @@ -612,7 +547,7 @@ const ProcessIOPreview = memo( ; }; - return ( + return ; }) ); @@ -656,19 +591,23 @@ const ProcessValuePreview = withStyles(styles)(({ value, classes }: ProcessValue interface ProcessIORawDataProps { data: ProcessIOParameter[]; + hidden?: boolean; } -const ProcessIORaw = withStyles(styles)(({ data }: ProcessIORawDataProps) => ( - - - +const ProcessIORaw = withStyles(styles)(({ data, hidden, classes }: ProcessIORawDataProps & WithStyles) => ( + )); interface ProcessInputMountsDataProps { mounts: InputCollectionMount[]; + hidden?: boolean; } type ProcessInputMountsProps = ProcessInputMountsDataProps & WithStyles; @@ -676,10 +615,11 @@ type ProcessInputMountsProps = ProcessInputMountsDataProps & WithStyles ({ auth: state.auth, - }))(({ mounts, classes, auth }: ProcessInputMountsProps & { auth: AuthState }) => ( + }))(({ mounts, hidden, classes, auth }: ProcessInputMountsProps & { auth: AuthState }) => ( @@ -708,6 +648,40 @@ const ProcessInputMounts = withStyles(styles)( )) ); +export interface ProcessOutputCollectionActionProps { + navigateTo: (uuid: string) => void; +} + +const mapNavigateToProps = (dispatch: Dispatch): ProcessOutputCollectionActionProps => ({ + navigateTo: uuid => dispatch(navigateTo(uuid)), +}); + +type ProcessOutputCollectionProps = {outputUuid: string | undefined, hidden?: boolean} & ProcessOutputCollectionActionProps & WithStyles; + +const ProcessOutputCollection = withStyles(styles)(connect(null, mapNavigateToProps)(({ outputUuid, hidden, navigateTo, classes }: ProcessOutputCollectionProps) => ( + +))); + type FileWithSecondaryFiles = { secondaryFiles: File[]; }; diff --git a/services/workbench2/src/views/run-process-panel/inputs/enum-input.tsx b/services/workbench2/src/views/run-process-panel/inputs/enum-input.tsx index 207a30acd0..e6a6b90cfe 100644 --- a/services/workbench2/src/views/run-process-panel/inputs/enum-input.tsx +++ b/services/workbench2/src/views/run-process-panel/inputs/enum-input.tsx @@ -5,7 +5,7 @@ import React from 'react'; import { Field } from 'redux-form'; import { memoize } from 'lodash/fp'; -import { require } from 'validators/require'; +import { fieldRequire } from 'validators/require'; import { Select, MenuItem } from '@material-ui/core'; import { EnumCommandInputParameter, CommandInputEnumSchema, isRequiredInput, getEnumType } from 'models/workflow'; import { GenericInputProps, GenericInput } from './generic-input'; @@ -17,7 +17,7 @@ export interface EnumInputProps { const getValidation = memoize( (input: EnumCommandInputParameter) => ([ isRequiredInput(input) - ? require + ? fieldRequire : () => undefined, ])); diff --git a/services/workbench2/src/views/run-process-panel/inputs/project-input.tsx b/services/workbench2/src/views/run-process-panel/inputs/project-input.tsx index 438bbe8e7e..b455135f3a 100644 --- a/services/workbench2/src/views/run-process-panel/inputs/project-input.tsx +++ b/services/workbench2/src/views/run-process-panel/inputs/project-input.tsx @@ -21,7 +21,7 @@ import { getUserUuid } from 'common/getuser'; export type ProjectCommandInputParameter = GenericCommandInputParameter; -const require: any = (value?: ProjectResource) => (value === undefined); +const isUndefined: any = (value?: ProjectResource) => (value === undefined); export interface ProjectInputProps { required: boolean; @@ -37,7 +37,7 @@ export const ProjectInput = ({ required, input, options }: ProjectInputProps) => commandInput={input} component={ProjectInputComponent as any} format={format} - validate={required ? require : undefined} + validate={required ? isUndefined : undefined} {...{ options, required diff --git a/services/workbench2/src/views/run-process-panel/inputs/string-input.tsx b/services/workbench2/src/views/run-process-panel/inputs/string-input.tsx index 543100db1f..e497004801 100644 --- a/services/workbench2/src/views/run-process-panel/inputs/string-input.tsx +++ b/services/workbench2/src/views/run-process-panel/inputs/string-input.tsx @@ -6,7 +6,7 @@ import React from 'react'; import { memoize } from 'lodash/fp'; import { isRequiredInput, StringCommandInputParameter } from 'models/workflow'; import { Field } from 'redux-form'; -import { require } from 'validators/require'; +import { fieldRequire } from 'validators/require'; import { GenericInputProps, GenericInput } from 'views/run-process-panel/inputs/generic-input'; import { Input as MaterialInput } from '@material-ui/core'; @@ -23,7 +23,7 @@ export const StringInput = ({ input }: StringInputProps) => const getValidation = memoize( (input: StringCommandInputParameter) => ([ isRequiredInput(input) - ? require + ? fieldRequire : () => undefined, ])); diff --git a/services/workbench2/src/views/search-results-panel/search-results-panel-view.tsx b/services/workbench2/src/views/search-results-panel/search-results-panel-view.tsx index e9693b50e5..ed11326481 100644 --- a/services/workbench2/src/views/search-results-panel/search-results-panel-view.tsx +++ b/services/workbench2/src/views/search-results-panel/search-results-panel-view.tsx @@ -149,14 +149,13 @@ export const SearchResultsPanelView = withStyles(styles, { withTheme: true })( setItemPath(tmpPath); } })(); - - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedItem]); const onItemClick = useCallback((uuid) => { setSelectedItem(uuid); props.onItemClick(uuid); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [props.onItemClick]); return diff --git a/services/workbench2/src/views/workbench/workbench.tsx b/services/workbench2/src/views/workbench/workbench.tsx index 3020e0d298..677a6a16e9 100644 --- a/services/workbench2/src/views/workbench/workbench.tsx +++ b/services/workbench2/src/views/workbench/workbench.tsx @@ -39,6 +39,7 @@ import { PartialMoveToNewCollectionDialog } from "views-components/dialog-forms/ import { PartialMoveToExistingCollectionDialog } from "views-components/dialog-forms/partial-move-to-existing-collection-dialog"; import { PartialMoveToSeparateCollectionsDialog } from "views-components/dialog-forms/partial-move-to-separate-collections-dialog"; import { RemoveProcessDialog } from "views-components/process-remove-dialog/process-remove-dialog"; +import { RemoveWorkflowDialog } from "views-components/workflow-remove-dialog/workflow-remove-dialog"; import { MainContentBar } from "views-components/main-content-bar/main-content-bar"; import { Grid } from "@material-ui/core"; import { TrashPanel } from "views/trash-panel/trash-panel"; @@ -322,7 +323,7 @@ const { classes, sidePanelIsCollapsed, isNotLinking, isTransitioning, isUserActi useEffect(()=>{ if (isTransitioning) applyCollapsedState(savedWidth); - // eslint-disable-next-line react-hooks/exhaustive-deps + // eslint-disable-next-line react-hooks/exhaustive-deps }, [isTransitioning, savedWidth]) applyCollapsedState(savedWidth); @@ -435,6 +436,7 @@ const { classes, sidePanelIsCollapsed, isNotLinking, isTransitioning, isUserActi + diff --git a/services/workbench2/tsconfig.json b/services/workbench2/tsconfig.json index 08f7108e62..e2ef08c80c 100644 --- a/services/workbench2/tsconfig.json +++ b/services/workbench2/tsconfig.json @@ -10,7 +10,7 @@ ], "sourceMap": true, "allowJs": true, - "jsx": "preserve", + "jsx": "react-jsx", "moduleResolution": "node", "rootDir": "src", "baseUrl": "src", @@ -34,6 +34,7 @@ "alwaysStrict": false, "strictFunctionTypes": false, "strictPropertyInitialization": false, + "noFallthroughCasesInSwitch": false }, "exclude": [ "node_modules", diff --git a/services/workbench2/yarn.lock b/services/workbench2/yarn.lock index 21fcc817c5..c098612c5d 100644 --- a/services/workbench2/yarn.lock +++ b/services/workbench2/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 6 cacheKey: 8 +"@aashutoshrathi/word-wrap@npm:^1.2.3": + version: 1.2.6 + resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" + checksum: ada901b9e7c680d190f1d012c84217ce0063d8f5c5a7725bb91ec3c5ed99bb7572680eb2d2938a531ccbaec39a95422fcd8a6b4a13110c7d98dd75402f66a0cd + languageName: node + linkType: hard + "@ampproject/remapping@npm:^2.2.0": version: 2.3.0 resolution: "@ampproject/remapping@npm:2.3.0" @@ -15,16 +22,25 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/code-frame@npm:7.8.3" +"@babel/code-frame@npm:7.10.4": + version: 7.10.4 + resolution: "@babel/code-frame@npm:7.10.4" + dependencies: + "@babel/highlight": ^7.10.4 + checksum: feb4543c8a509fe30f0f6e8d7aa84f82b41148b963b826cd330e34986f649a85cb63b2f13dd4effdf434ac555d16f14940b8ea5f4433297c2f5ff85486ded019 + languageName: node + linkType: hard + +"@babel/code-frame@npm:7.12.11": + version: 7.12.11 + resolution: "@babel/code-frame@npm:7.12.11" dependencies: - "@babel/highlight": ^7.8.3 - checksum: 5f3172b0c8d5db625fb88c9f6ab909cb164645152176dfa14c927c19c0774c41fa9ba494cb19cb5d152a414bd6732c41eae708f9f635e02a4ed0889ac239fe4c + "@babel/highlight": ^7.10.4 + checksum: 3963eff3ebfb0e091c7e6f99596ef4b258683e4ba8a134e4e95f77afe85be5c931e184fff6435fb4885d12eba04a5e25532f7fbc292ca13b48e7da943474e2f3 languageName: node linkType: hard -"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.14.5, @babel/code-frame@npm:^7.8.3": +"@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.14.5": version: 7.14.5 resolution: "@babel/code-frame@npm:7.14.5" dependencies: @@ -33,7 +49,7 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2": +"@babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.24.1, @babel/code-frame@npm:^7.24.2, @babel/code-frame@npm:^7.5.5": version: 7.24.2 resolution: "@babel/code-frame@npm:7.24.2" dependencies: @@ -43,45 +59,45 @@ __metadata: languageName: node linkType: hard -"@babel/compat-data@npm:^7.13.11, @babel/compat-data@npm:^7.14.5, @babel/compat-data@npm:^7.14.7, @babel/compat-data@npm:^7.9.0": +"@babel/compat-data@npm:^7.14.5": version: 7.14.7 resolution: "@babel/compat-data@npm:7.14.7" checksum: dcf7a72cb650206857a98cce1ab0973e67689f19afc3b30cabff6dbddf563f188d54d3b3f92a70c6bc1feb9049d8b2e601540e1d435b6866c77bffad0a441c9f languageName: node linkType: hard -"@babel/compat-data@npm:^7.23.5": +"@babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.23.5, @babel/compat-data@npm:^7.24.4": version: 7.24.4 resolution: "@babel/compat-data@npm:7.24.4" checksum: 52ce371658dc7796c9447c9cb3b9c0659370d141b76997f21c5e0028cca4d026ca546b84bc8d157ce7ca30bd353d89f9238504eb8b7aefa9b1f178b4c100c2d4 languageName: node linkType: hard -"@babel/core@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/core@npm:7.9.0" +"@babel/core@npm:7.12.3": + version: 7.12.3 + resolution: "@babel/core@npm:7.12.3" dependencies: - "@babel/code-frame": ^7.8.3 - "@babel/generator": ^7.9.0 - "@babel/helper-module-transforms": ^7.9.0 - "@babel/helpers": ^7.9.0 - "@babel/parser": ^7.9.0 - "@babel/template": ^7.8.6 - "@babel/traverse": ^7.9.0 - "@babel/types": ^7.9.0 + "@babel/code-frame": ^7.10.4 + "@babel/generator": ^7.12.1 + "@babel/helper-module-transforms": ^7.12.1 + "@babel/helpers": ^7.12.1 + "@babel/parser": ^7.12.3 + "@babel/template": ^7.10.4 + "@babel/traverse": ^7.12.1 + "@babel/types": ^7.12.1 convert-source-map: ^1.7.0 debug: ^4.1.0 gensync: ^1.0.0-beta.1 json5: ^2.1.2 - lodash: ^4.17.13 + lodash: ^4.17.19 resolve: ^1.3.2 semver: ^5.4.1 source-map: ^0.5.0 - checksum: 0886b35c9cda80628bc61e47172c79d51ab1d1e693f95c037df371bf0a84ca5cd72c0183fb3d01f47c59395d7805d2e79d46660488d73b9966db5fb726ad561c + checksum: 29ee14dd7ae66c1af84d1b2864e1e9e1bec23b89f41e414917b10151ae1fcb6d3b6a8a25d028a7e22dba3bb7b69eb1f7f0d844797341357e36fa71ff967fb4a5 languageName: node linkType: hard -"@babel/core@npm:^7.0.0": +"@babel/core@npm:^7.0.0, @babel/core@npm:^7.12.3, @babel/core@npm:^7.16.0, @babel/core@npm:^7.7.5, @babel/core@npm:^7.8.4, @babel/core@npm:^7.9.0": version: 7.24.4 resolution: "@babel/core@npm:7.24.4" dependencies: @@ -104,7 +120,7 @@ __metadata: languageName: node linkType: hard -"@babel/core@npm:^7.1.0, @babel/core@npm:^7.4.5": +"@babel/core@npm:^7.1.0": version: 7.14.6 resolution: "@babel/core@npm:7.14.6" dependencies: @@ -127,18 +143,7 @@ __metadata: languageName: node linkType: hard -"@babel/generator@npm:^7.14.5, @babel/generator@npm:^7.4.0, @babel/generator@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/generator@npm:7.14.5" - dependencies: - "@babel/types": ^7.14.5 - jsesc: ^2.5.1 - source-map: ^0.5.0 - checksum: 7fcfeaf17e8e76ea91c66dc86c776d2112f52ce0315d3f4ca6a74b6eada0be1592d1ea6286d7241d3f634b63717ceef5d180d041a0b3dca9d071ba2e5fa7c77b - languageName: node - linkType: hard - -"@babel/generator@npm:^7.24.1, @babel/generator@npm:^7.24.4": +"@babel/generator@npm:^7.12.1, @babel/generator@npm:^7.24.1, @babel/generator@npm:^7.24.4": version: 7.24.4 resolution: "@babel/generator@npm:7.24.4" dependencies: @@ -150,26 +155,36 @@ __metadata: languageName: node linkType: hard -"@babel/helper-annotate-as-pure@npm:^7.14.5": +"@babel/generator@npm:^7.14.5": version: 7.14.5 - resolution: "@babel/helper-annotate-as-pure@npm:7.14.5" + resolution: "@babel/generator@npm:7.14.5" dependencies: "@babel/types": ^7.14.5 - checksum: 18cefedda60003c2551dabe0e4ad278ef0507682680892c60e9f7cb75ae1dc9a065cddb3ce9964da76f220bf972af5262619eeac4b84c2b8aba1b031961215cc + jsesc: ^2.5.1 + source-map: ^0.5.0 + checksum: 7fcfeaf17e8e76ea91c66dc86c776d2112f52ce0315d3f4ca6a74b6eada0be1592d1ea6286d7241d3f634b63717ceef5d180d041a0b3dca9d071ba2e5fa7c77b languageName: node linkType: hard -"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.14.5" +"@babel/helper-annotate-as-pure@npm:^7.18.6, @babel/helper-annotate-as-pure@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-annotate-as-pure@npm:7.22.5" dependencies: - "@babel/helper-explode-assignable-expression": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: 0d3571edff0a96d625503a3fd79643f66f8a5204e75c4351276c0d194240e1debe322a70ef9ff47952bd77ac76792f42d732922b00b5bd8b6e2c99909dc4f49b + "@babel/types": ^7.22.5 + checksum: 53da330f1835c46f26b7bf4da31f7a496dee9fd8696cca12366b94ba19d97421ce519a74a837f687749318f94d1a37f8d1abcbf35e8ed22c32d16373b2f6198d + languageName: node + linkType: hard + +"@babel/helper-builder-binary-assignment-operator-visitor@npm:^7.22.15": + version: 7.22.15 + resolution: "@babel/helper-builder-binary-assignment-operator-visitor@npm:7.22.15" + dependencies: + "@babel/types": ^7.22.15 + checksum: 639c697a1c729f9fafa2dd4c9af2e18568190299b5907bd4c2d0bc818fcbd1e83ffeecc2af24327a7faa7ac4c34edd9d7940510a5e66296c19bad17001cf5c7a languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.13.0, @babel/helper-compilation-targets@npm:^7.14.5, @babel/helper-compilation-targets@npm:^7.8.7": +"@babel/helper-compilation-targets@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-compilation-targets@npm:7.14.5" dependencies: @@ -183,7 +198,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-compilation-targets@npm:^7.23.6": +"@babel/helper-compilation-targets@npm:^7.22.6, @babel/helper-compilation-targets@npm:^7.23.6": version: 7.23.6 resolution: "@babel/helper-compilation-targets@npm:7.23.6" dependencies: @@ -196,49 +211,50 @@ __metadata: languageName: node linkType: hard -"@babel/helper-create-class-features-plugin@npm:^7.14.5, @babel/helper-create-class-features-plugin@npm:^7.14.6, @babel/helper-create-class-features-plugin@npm:^7.8.3": - version: 7.14.6 - resolution: "@babel/helper-create-class-features-plugin@npm:7.14.6" +"@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.24.1, @babel/helper-create-class-features-plugin@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/helper-create-class-features-plugin@npm:7.24.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-function-name": ^7.14.5 - "@babel/helper-member-expression-to-functions": ^7.14.5 - "@babel/helper-optimise-call-expression": ^7.14.5 - "@babel/helper-replace-supers": ^7.14.5 - "@babel/helper-split-export-declaration": ^7.14.5 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-member-expression-to-functions": ^7.23.0 + "@babel/helper-optimise-call-expression": ^7.22.5 + "@babel/helper-replace-supers": ^7.24.1 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/helper-split-export-declaration": ^7.22.6 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: 9d9c3c6f469bc5da4e5819979d0f70bf8a824967661743800741b5560cfa3cf811d52ab14dc00dd6e839814f8db39cf3118c08d550c487680969c40c9ccf2e2a + checksum: 75b0a51ae1f7232932559779b78711c271404d02d069156d1bd9a7982c165c5134058d2ec2d8b5f2e42026ee4f52ba2a30c86a7aa3bce6b5fd0991eb721abc8c languageName: node linkType: hard -"@babel/helper-create-regexp-features-plugin@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-create-regexp-features-plugin@npm:7.14.5" +"@babel/helper-create-regexp-features-plugin@npm:^7.18.6, @babel/helper-create-regexp-features-plugin@npm:^7.22.15, @babel/helper-create-regexp-features-plugin@npm:^7.22.5": + version: 7.22.15 + resolution: "@babel/helper-create-regexp-features-plugin@npm:7.22.15" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - regexpu-core: ^4.7.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + regexpu-core: ^5.3.1 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0 - checksum: c2636d0a6ea6d57eb3603ba9b223fd6ec273a3d8171eb8d84a357ff028cd747ab383b1d7cef84a4df5f9aebb321d43599895f562f3c8aa96314d4847aa59710e + checksum: 0243b8d4854f1dc8861b1029a46d3f6393ad72f366a5a08e36a4648aa682044f06da4c6e87a456260e1e1b33c999f898ba591a0760842c1387bcc93fbf2151a6 languageName: node linkType: hard -"@babel/helper-define-polyfill-provider@npm:^0.2.2": - version: 0.2.3 - resolution: "@babel/helper-define-polyfill-provider@npm:0.2.3" +"@babel/helper-define-polyfill-provider@npm:^0.6.1": + version: 0.6.1 + resolution: "@babel/helper-define-polyfill-provider@npm:0.6.1" dependencies: - "@babel/helper-compilation-targets": ^7.13.0 - "@babel/helper-module-imports": ^7.12.13 - "@babel/helper-plugin-utils": ^7.13.0 - "@babel/traverse": ^7.13.0 + "@babel/helper-compilation-targets": ^7.22.6 + "@babel/helper-plugin-utils": ^7.22.5 debug: ^4.1.1 lodash.debounce: ^4.0.8 resolve: ^1.14.2 - semver: ^6.1.2 peerDependencies: - "@babel/core": ^7.4.0-0 - checksum: 797699fe870e45bdbc7c4128963427f7d6240609b700b3f2c0a2f2f187e5f848ba704bcfe58d7d91796cabc5001fae01746b3efda113beb5b5b824927cf59fdb + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: b45deb37ce1342d862422e81a3d25ff55f9c7ca52fe303405641e2add8db754091aaaa2119047a0f0b85072221fbddaa92adf53104274661d2795783b56bea2c languageName: node linkType: hard @@ -249,27 +265,7 @@ __metadata: languageName: node linkType: hard -"@babel/helper-explode-assignable-expression@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-explode-assignable-expression@npm:7.14.5" - dependencies: - "@babel/types": ^7.14.5 - checksum: f3b34c54ad26e48e1409f21aaac8ee5b5fa3bd2917ce4df496f57daec12b6132b2d5c2618da807458e97bc2d7894c5bf505cc96789e0c289dcc9948d7844bb03 - languageName: node - linkType: hard - -"@babel/helper-function-name@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-function-name@npm:7.14.5" - dependencies: - "@babel/helper-get-function-arity": ^7.14.5 - "@babel/template": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: fd8ffa82f7622b6e9a6294fb3b98b42e743ab2a8e3c329367667a960b5b98b48bc5ebf8be7308981f1985b9f3c69e1a3b4a91c8944ae97c31803240da92fb3c8 - languageName: node - linkType: hard - -"@babel/helper-function-name@npm:^7.23.0": +"@babel/helper-function-name@npm:^7.22.5, @babel/helper-function-name@npm:^7.23.0": version: 7.23.0 resolution: "@babel/helper-function-name@npm:7.23.0" dependencies: @@ -279,24 +275,6 @@ __metadata: languageName: node linkType: hard -"@babel/helper-get-function-arity@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-get-function-arity@npm:7.14.5" - dependencies: - "@babel/types": ^7.14.5 - checksum: a60779918b677a35e177bb4f46babfd54e9790587b6a4f076092a9eff2a940cbeacdeb10c94331b26abfe838769554d72293d16df897246cfccd1444e5e27cb7 - languageName: node - linkType: hard - -"@babel/helper-hoist-variables@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-hoist-variables@npm:7.14.5" - dependencies: - "@babel/types": ^7.14.5 - checksum: 35af58eebffca10988de7003e044ce2d27212aea72ac6d2c4604137da7f1e193cc694d8d60805d0d0beaf3d990f6f2dcc2622c52e3d3148e37017a29cacf2e56 - languageName: node - linkType: hard - "@babel/helper-hoist-variables@npm:^7.22.5": version: 7.22.5 resolution: "@babel/helper-hoist-variables@npm:7.22.5" @@ -315,16 +293,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.14.5, @babel/helper-module-imports@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/helper-module-imports@npm:7.14.5" +"@babel/helper-member-expression-to-functions@npm:^7.23.0": + version: 7.23.0 + resolution: "@babel/helper-member-expression-to-functions@npm:7.23.0" dependencies: - "@babel/types": ^7.14.5 - checksum: b98279908698a50a22634e683924cb25eb93edf1bf28ac65691dfa82d7a1a4dae4e6b12b8ef9f9a50171ca484620bce544f270873c53505d8a45364c5b665c0c + "@babel/types": ^7.23.0 + checksum: 494659361370c979ada711ca685e2efe9460683c36db1b283b446122596602c901e291e09f2f980ecedfe6e0f2bd5386cb59768285446530df10c14df1024e75 languageName: node linkType: hard -"@babel/helper-module-imports@npm:^7.22.15": +"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.22.15, @babel/helper-module-imports@npm:^7.24.1, @babel/helper-module-imports@npm:^7.24.3": version: 7.24.3 resolution: "@babel/helper-module-imports@npm:7.24.3" dependencies: @@ -333,23 +311,16 @@ __metadata: languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.14.5, @babel/helper-module-transforms@npm:^7.9.0": +"@babel/helper-module-imports@npm:^7.14.5": version: 7.14.5 - resolution: "@babel/helper-module-transforms@npm:7.14.5" + resolution: "@babel/helper-module-imports@npm:7.14.5" dependencies: - "@babel/helper-module-imports": ^7.14.5 - "@babel/helper-replace-supers": ^7.14.5 - "@babel/helper-simple-access": ^7.14.5 - "@babel/helper-split-export-declaration": ^7.14.5 - "@babel/helper-validator-identifier": ^7.14.5 - "@babel/template": ^7.14.5 - "@babel/traverse": ^7.14.5 "@babel/types": ^7.14.5 - checksum: f5d64c0242ec8949ee09069a634d28ae750ab22f9533ea90eab9eaf3405032a33b0b329a63fac0a7901482efb8a388a06279f7544225a0bc3c1b92b306ab2b6e + checksum: b98279908698a50a22634e683924cb25eb93edf1bf28ac65691dfa82d7a1a4dae4e6b12b8ef9f9a50171ca484620bce544f270873c53505d8a45364c5b665c0c languageName: node linkType: hard -"@babel/helper-module-transforms@npm:^7.23.3": +"@babel/helper-module-transforms@npm:^7.12.1, @babel/helper-module-transforms@npm:^7.23.3": version: 7.23.3 resolution: "@babel/helper-module-transforms@npm:7.23.3" dependencies: @@ -364,6 +335,22 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/helper-module-transforms@npm:7.14.5" + dependencies: + "@babel/helper-module-imports": ^7.14.5 + "@babel/helper-replace-supers": ^7.14.5 + "@babel/helper-simple-access": ^7.14.5 + "@babel/helper-split-export-declaration": ^7.14.5 + "@babel/helper-validator-identifier": ^7.14.5 + "@babel/template": ^7.14.5 + "@babel/traverse": ^7.14.5 + "@babel/types": ^7.14.5 + checksum: f5d64c0242ec8949ee09069a634d28ae750ab22f9533ea90eab9eaf3405032a33b0b329a63fac0a7901482efb8a388a06279f7544225a0bc3c1b92b306ab2b6e + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-optimise-call-expression@npm:7.14.5" @@ -373,21 +360,39 @@ __metadata: languageName: node linkType: hard -"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.13.0, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": +"@babel/helper-optimise-call-expression@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-optimise-call-expression@npm:7.22.5" + dependencies: + "@babel/types": ^7.22.5 + checksum: c70ef6cc6b6ed32eeeec4482127e8be5451d0e5282d5495d5d569d39eb04d7f1d66ec99b327f45d1d5842a9ad8c22d48567e93fc502003a47de78d122e355f7c + languageName: node + linkType: hard + +"@babel/helper-plugin-utils@npm:^7.0.0, @babel/helper-plugin-utils@npm:^7.10.4, @babel/helper-plugin-utils@npm:^7.12.13, @babel/helper-plugin-utils@npm:^7.14.5, @babel/helper-plugin-utils@npm:^7.8.0, @babel/helper-plugin-utils@npm:^7.8.3": version: 7.14.5 resolution: "@babel/helper-plugin-utils@npm:7.14.5" checksum: fe20e90a24d02770a60ebe80ab9f0dfd7258503cea8006c71709ac9af1aa3e47b0de569499673f11ea6c99597f8c0e4880ae1d505986e61101b69716820972fe languageName: node linkType: hard -"@babel/helper-remap-async-to-generator@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-remap-async-to-generator@npm:7.14.5" +"@babel/helper-plugin-utils@npm:^7.18.6, @babel/helper-plugin-utils@npm:^7.20.2, @babel/helper-plugin-utils@npm:^7.22.5, @babel/helper-plugin-utils@npm:^7.24.0": + version: 7.24.0 + resolution: "@babel/helper-plugin-utils@npm:7.24.0" + checksum: e2baa0eede34d2fa2265947042aa84d444aa48dc51e9feedea55b67fc1bc3ab051387e18b33ca7748285a6061390831ab82f8a2c767d08470b93500ec727e9b9 + languageName: node + linkType: hard + +"@babel/helper-remap-async-to-generator@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-remap-async-to-generator@npm:7.22.20" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-wrap-function": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: 022594a15caed0d3bbac52e27eef0f20f9dceb85921b682df55f3bb21dee6fea645b03663e84fdfaadc6b88f4b83b012858520813c15e88728bbc5e16bf3fa29 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-wrap-function": ^7.22.20 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 2fe6300a6f1b58211dffa0aed1b45d4958506d096543663dba83bd9251fe8d670fa909143a65b45e72acb49e7e20fbdb73eae315d9ddaced467948c3329986e7 languageName: node linkType: hard @@ -403,6 +408,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-replace-supers@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/helper-replace-supers@npm:7.24.1" + dependencies: + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-member-expression-to-functions": ^7.23.0 + "@babel/helper-optimise-call-expression": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: c04182c34a3195c6396de2f2945f86cb60daa94ca7392db09bd8b0d4e7a15b02fbe1947c70f6062c87eadaea6d7135207129efa35cf458ea0987bab8c0f02d5a + languageName: node + linkType: hard + "@babel/helper-simple-access@npm:^7.14.5": version: 7.14.5 resolution: "@babel/helper-simple-access@npm:7.14.5" @@ -421,12 +439,12 @@ __metadata: languageName: node linkType: hard -"@babel/helper-skip-transparent-expression-wrappers@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.14.5" +"@babel/helper-skip-transparent-expression-wrappers@npm:^7.20.0, @babel/helper-skip-transparent-expression-wrappers@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/helper-skip-transparent-expression-wrappers@npm:7.22.5" dependencies: - "@babel/types": ^7.14.5 - checksum: d16937eb08d57d2577902fa6d05ac4b1695602babd9dff9890fa8e56b593fdc997ad24de13fdaf15617036bfacf3493ea569898a5ac0538c2a831aa163f18985 + "@babel/types": ^7.22.5 + checksum: 1012ef2295eb12dc073f2b9edf3425661e9b8432a3387e62a8bc27c42963f1f216ab3124228015c748770b2257b4f1fda882ca8fa34c0bf485e929ae5bc45244 languageName: node linkType: hard @@ -490,30 +508,18 @@ __metadata: languageName: node linkType: hard -"@babel/helper-wrap-function@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/helper-wrap-function@npm:7.14.5" - dependencies: - "@babel/helper-function-name": ^7.14.5 - "@babel/template": ^7.14.5 - "@babel/traverse": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: d5c4bec02396f00d305ae2b60cfa5f3ec27d196a71b88107745b6be4fe257ebe54deedb6ee3997c8c9a2cc5c2571d567c22e9b866109490a2aa7f79a1a2272e2 - languageName: node - linkType: hard - -"@babel/helpers@npm:^7.14.6, @babel/helpers@npm:^7.9.0": - version: 7.14.6 - resolution: "@babel/helpers@npm:7.14.6" +"@babel/helper-wrap-function@npm:^7.22.20": + version: 7.22.20 + resolution: "@babel/helper-wrap-function@npm:7.22.20" dependencies: - "@babel/template": ^7.14.5 - "@babel/traverse": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: fe4e73975b062a8b8b95f499f4ac1064c9a53d4ee83cc273c2420250f6a46b59f1f5e35050d41ebe04efd7885a28ceea6f4f16d8eb091e24622f2a4a5eb20f23 + "@babel/helper-function-name": ^7.22.5 + "@babel/template": ^7.22.15 + "@babel/types": ^7.22.19 + checksum: 221ed9b5572612aeb571e4ce6a256f2dee85b3c9536f1dd5e611b0255e5f59a3d0ec392d8d46d4152149156a8109f92f20379b1d6d36abb613176e0e33f05fca languageName: node linkType: hard -"@babel/helpers@npm:^7.24.4": +"@babel/helpers@npm:^7.12.1, @babel/helpers@npm:^7.24.4": version: 7.24.4 resolution: "@babel/helpers@npm:7.24.4" dependencies: @@ -524,18 +530,18 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.14.5, @babel/highlight@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/highlight@npm:7.14.5" +"@babel/helpers@npm:^7.14.6": + version: 7.14.6 + resolution: "@babel/helpers@npm:7.14.6" dependencies: - "@babel/helper-validator-identifier": ^7.14.5 - chalk: ^2.0.0 - js-tokens: ^4.0.0 - checksum: 4e4b22fb886c939551d73307de16232c186fdb4d8ec8f514541b058feaecdba5234788a0740ca5bcd28777f4108596c39ac4b7463684c63b3812f6071e3fb88f + "@babel/template": ^7.14.5 + "@babel/traverse": ^7.14.5 + "@babel/types": ^7.14.5 + checksum: fe4e73975b062a8b8b95f499f4ac1064c9a53d4ee83cc273c2420250f6a46b59f1f5e35050d41ebe04efd7885a28ceea6f4f16d8eb091e24622f2a4a5eb20f23 languageName: node linkType: hard -"@babel/highlight@npm:^7.24.2": +"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.24.2": version: 7.24.2 resolution: "@babel/highlight@npm:7.24.2" dependencies: @@ -547,7 +553,18 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.5, @babel/parser@npm:^7.14.6, @babel/parser@npm:^7.4.3, @babel/parser@npm:^7.7.0, @babel/parser@npm:^7.9.0": +"@babel/highlight@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/highlight@npm:7.14.5" + dependencies: + "@babel/helper-validator-identifier": ^7.14.5 + chalk: ^2.0.0 + js-tokens: ^4.0.0 + checksum: 4e4b22fb886c939551d73307de16232c186fdb4d8ec8f514541b058feaecdba5234788a0740ca5bcd28777f4108596c39ac4b7463684c63b3812f6071e3fb88f + languageName: node + linkType: hard + +"@babel/parser@npm:^7.1.0, @babel/parser@npm:^7.14.5, @babel/parser@npm:^7.14.6, @babel/parser@npm:^7.7.0": version: 7.14.7 resolution: "@babel/parser@npm:7.14.7" bin: @@ -556,7 +573,7 @@ __metadata: languageName: node linkType: hard -"@babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1, @babel/parser@npm:^7.24.4": +"@babel/parser@npm:^7.12.3, @babel/parser@npm:^7.14.7, @babel/parser@npm:^7.20.7, @babel/parser@npm:^7.24.0, @babel/parser@npm:^7.24.1, @babel/parser@npm:^7.24.4": version: 7.24.4 resolution: "@babel/parser@npm:7.24.4" bin: @@ -565,346 +582,273 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.14.5" +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-bugfix-firefox-class-in-computed-class-key@npm:7.24.4" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.14.5 - "@babel/plugin-proposal-optional-chaining": ^7.14.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: - "@babel/core": ^7.13.0 - checksum: 17331fd4c1de860ac78aa3195eb5bd058c4eb24a8f2c6e719f079f9c86cbdb53d9a8affc2f9f78b6fc257afef03811922c2d16addad5d5f6224d2820da1c9f45 + "@babel/core": ^7.0.0 + checksum: 0be3f41b1b865d7a4ed1a432337be48de67989d0b4e47def34a05097a804b6fc193115f97c954fd757339e0b80030ecf1d0a3d3fd6e7e91718644de0a5aae3d3 languageName: node linkType: hard -"@babel/plugin-proposal-async-generator-functions@npm:^7.14.7, @babel/plugin-proposal-async-generator-functions@npm:^7.8.3": - version: 7.14.7 - resolution: "@babel/plugin-proposal-async-generator-functions@npm:7.14.7" +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-remap-async-to-generator": ^7.14.5 - "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 09343a79385615f8d5f95aaef7c44af5e899c82f030f3d73546c2ffffa567c0949f0405052d7e32f643c0eb2a23590a5050f4606855b3506246d3d60e46f32e3 + "@babel/core": ^7.0.0 + checksum: ec5fddc8db6de0e0082a883f21141d6f4f9f9f0bc190d662a732b5e9a506aae5d7d2337049a1bf055d7cb7add6f128036db6d4f47de5e9ac1be29e043c8b7ca8 languageName: node linkType: hard -"@babel/plugin-proposal-class-properties@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-proposal-class-properties@npm:7.8.3" +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.8.3 - "@babel/helper-plugin-utils": ^7.8.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/plugin-transform-optional-chaining": ^7.24.1 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 5ac3435b0393b09162234f8e4c56c6321f038d205af447563f8389e7ed447904c4cdedf958e6a5ed092692fcc2eff980913efff19589c0969dd9846be4710867 + "@babel/core": ^7.13.0 + checksum: e18235463e716ac2443938aaec3c18b40c417a1746fba0fa4c26cf4d71326b76ef26c002081ab1b445abfae98e063d561519aa55672dddc1ef80b3940211ffbb languageName: node linkType: hard -"@babel/plugin-proposal-class-properties@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-class-properties@npm:7.14.5" +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: fe2aa0a44f8ea121e10c856d6fb4fca418dc42451258ef6ed29321ca740080fba420ebd3d6700d0456c34c2ab2044f9ce4308498321f52a93184ff5adb015aae + "@babel/core": ^7.0.0 + checksum: b5e5889ce5ef51e813e3063cd548f55eb3c88e925c3c08913f334e15d62496861e538ae52a3974e0c56a3044ed8fd5033faea67a64814324af56edc9865b7359 languageName: node linkType: hard -"@babel/plugin-proposal-class-static-block@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-class-static-block@npm:7.14.5" +"@babel/plugin-proposal-class-properties@npm:^7.16.0": + version: 7.18.6 + resolution: "@babel/plugin-proposal-class-properties@npm:7.18.6" dependencies: - "@babel/helper-create-class-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-class-static-block": ^7.14.5 + "@babel/helper-create-class-features-plugin": ^7.18.6 + "@babel/helper-plugin-utils": ^7.18.6 peerDependencies: - "@babel/core": ^7.12.0 - checksum: 0275d0643dacd08638c2d3c129158ad0c2dea6a26e78fa4b2129811a29460ff9a6459d1955a19bfa3b9ed67ba2bb3c88676823ad207b2de4f0c65e0c3751d75c + "@babel/core": ^7.0.0-0 + checksum: 49a78a2773ec0db56e915d9797e44fd079ab8a9b2e1716e0df07c92532f2c65d76aeda9543883916b8e0ff13606afeffa67c5b93d05b607bc87653ad18a91422 languageName: node linkType: hard -"@babel/plugin-proposal-decorators@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-proposal-decorators@npm:7.8.3" +"@babel/plugin-proposal-decorators@npm:^7.16.4": + version: 7.24.1 + resolution: "@babel/plugin-proposal-decorators@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.8.3 - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-syntax-decorators": ^7.8.3 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-decorators": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f9aa852dd77657d29c19b16bc3a7d8c30e5964a9aa8eb541bf440f34659693631793d4c798c92e344e767c9ccc43baae9e595d86e589bfa4bb157fc07a5e0c05 + checksum: b9375c64656bf9ae6d2eeb965c40823e6447f0f4594979d037231884c0f3a92af97172087f35a05e90b8ca0ccb47551b013998e85853c1c634d47b341f4deece languageName: node linkType: hard -"@babel/plugin-proposal-dynamic-import@npm:^7.14.5, @babel/plugin-proposal-dynamic-import@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-proposal-dynamic-import@npm:7.14.5" +"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.16.0": + version: 7.18.6 + resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.18.6" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-dynamic-import": ^7.8.3 + "@babel/helper-plugin-utils": ^7.18.6 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 47be4b5f8824f8690b47d99a34d52de0e6c19d0b99f26c1f9a2e4cc49e05082bcef7248c610bb3830ae84cec928713c7774f4929fca4fa72df570df7a76a9d2b + checksum: 949c9ddcdecdaec766ee610ef98f965f928ccc0361dd87cf9f88cf4896a6ccd62fce063d4494778e50da99dea63d270a1be574a62d6ab81cbe9d85884bf55a7d languageName: node linkType: hard -"@babel/plugin-proposal-export-namespace-from@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-export-namespace-from@npm:7.14.5" +"@babel/plugin-proposal-numeric-separator@npm:^7.16.0": + version: 7.18.6 + resolution: "@babel/plugin-proposal-numeric-separator@npm:7.18.6" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/helper-plugin-utils": ^7.18.6 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b3f4e0cc196f7ad9132816bb350124e8932bc047ab946e431f85bae9649b0de384c54261a60c050a2b8220703408fc089f90349ad008ed69a70944a6f3048d0e + checksum: f370ea584c55bf4040e1f78c80b4eeb1ce2e6aaa74f87d1a48266493c33931d0b6222d8cee3a082383d6bb648ab8d6b7147a06f974d3296ef3bc39c7851683ec languageName: node linkType: hard -"@babel/plugin-proposal-json-strings@npm:^7.14.5, @babel/plugin-proposal-json-strings@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-proposal-json-strings@npm:7.14.5" +"@babel/plugin-proposal-optional-chaining@npm:^7.16.0": + version: 7.21.0 + resolution: "@babel/plugin-proposal-optional-chaining@npm:7.21.0" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/helper-plugin-utils": ^7.20.2 + "@babel/helper-skip-transparent-expression-wrappers": ^7.20.0 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 51dafe70237860569c9c27dc6a0db83e149bf7babb0fcafa9dbcd55a960b443f7b5bb695956c6e116e46b3dbd2a6777ead62bcad843aff8c1916c1be56e2f504 + checksum: 11c5449e01b18bb8881e8e005a577fa7be2fe5688e2382c8822d51f8f7005342a301a46af7b273b1f5645f9a7b894c428eee8526342038a275ef6ba4c8d8d746 languageName: node linkType: hard -"@babel/plugin-proposal-logical-assignment-operators@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-logical-assignment-operators@npm:7.14.5" +"@babel/plugin-proposal-private-methods@npm:^7.16.0": + version: 7.18.6 + resolution: "@babel/plugin-proposal-private-methods@npm:7.18.6" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 + "@babel/helper-create-class-features-plugin": ^7.18.6 + "@babel/helper-plugin-utils": ^7.18.6 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 08b6dbc991c4824b0d8bfabf46c8254fce02d2df04627b8849cf15a4b6de75629c10c7c83d1e6834cdcebfc98b16264ce2dd32aa9c0fae900ed2af807d5ac42b + checksum: 22d8502ee96bca99ad2c8393e8493e2b8d4507576dd054490fd8201a36824373440106f5b098b6d821b026c7e72b0424ff4aeca69ed5f42e48f029d3a156d5ad languageName: node linkType: hard -"@babel/plugin-proposal-nullish-coalescing-operator@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.8.3" - dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.0 +"@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2": + version: 7.21.0-placeholder-for-preset-env.2 + resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.0-placeholder-for-preset-env.2" peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 36a87fa8f0ca709f66671ebd1af3f865fd1798e59cbf57f8db71cf69ef15ee8cf21ec54833b34c5e77b8a5a60d5b4e9ae949c00fec8eb320d5bc299bfcc3eae1 + checksum: d97745d098b835d55033ff3a7fb2b895b9c5295b08a5759e4f20df325aa385a3e0bc9bd5ad8f2ec554a44d4e6525acfc257b8c5848a1345cb40f26a30e277e91 languageName: node linkType: hard -"@babel/plugin-proposal-nullish-coalescing-operator@npm:^7.14.5, @babel/plugin-proposal-nullish-coalescing-operator@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-proposal-nullish-coalescing-operator@npm:7.14.5" +"@babel/plugin-proposal-private-property-in-object@npm:^7.16.0": + version: 7.21.11 + resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.21.11" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/helper-annotate-as-pure": ^7.18.6 + "@babel/helper-create-class-features-plugin": ^7.21.0 + "@babel/helper-plugin-utils": ^7.20.2 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 033d9483c2feb74928fbb83a73948eb1179c8852d2ae507fbfc37752d2dbf702c9ad0daaf1eaa029f81b12b7e2470061b4f611db88b7293f0e9a71eba288a430 + checksum: 1b880543bc5f525b360b53d97dd30807302bb82615cd42bf931968f59003cac75629563d6b104868db50abd22235b3271fdf679fea5db59a267181a99cc0c265 languageName: node linkType: hard -"@babel/plugin-proposal-numeric-separator@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-proposal-numeric-separator@npm:7.8.3" +"@babel/plugin-syntax-async-generators@npm:^7.8.4": + version: 7.8.4 + resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-syntax-numeric-separator": ^7.8.3 + "@babel/helper-plugin-utils": ^7.8.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: fd2d926e5bba27180e79c7511cb62d423a74690419f97ae1804b4a36632017ab2ef763ce2a84810b7c350a5d3e42a8e263780dadefa4ad6288923a2d13950170 + checksum: 7ed1c1d9b9e5b64ef028ea5e755c0be2d4e5e4e3d6cf7df757b9a8c4cfa4193d268176d0f1f7fbecdda6fe722885c7fda681f480f3741d8a2d26854736f05367 languageName: node linkType: hard -"@babel/plugin-proposal-numeric-separator@npm:^7.14.5, @babel/plugin-proposal-numeric-separator@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-proposal-numeric-separator@npm:7.14.5" +"@babel/plugin-syntax-bigint@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-bigint@npm:7.8.3" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-numeric-separator": ^7.10.4 + "@babel/helper-plugin-utils": ^7.8.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 22093297ec9aed3938b39f4efa1b518252fe7b0835902c3066f0ae6a864ac253b986a4a21a6092aa068d0702d7b09bed74e56cf39f2da8b4f3f43e0747bffb62 + checksum: 3a10849d83e47aec50f367a9e56a6b22d662ddce643334b087f9828f4c3dd73bdc5909aaeabe123fed78515767f9ca43498a0e621c438d1cd2802d7fae3c9648 languageName: node linkType: hard -"@babel/plugin-proposal-object-rest-spread@npm:^7.14.7, @babel/plugin-proposal-object-rest-spread@npm:^7.9.0": - version: 7.14.7 - resolution: "@babel/plugin-proposal-object-rest-spread@npm:7.14.7" +"@babel/plugin-syntax-class-properties@npm:^7.12.13, @babel/plugin-syntax-class-properties@npm:^7.8.3": + version: 7.12.13 + resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" dependencies: - "@babel/compat-data": ^7.14.7 - "@babel/helper-compilation-targets": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-object-rest-spread": ^7.8.3 - "@babel/plugin-transform-parameters": ^7.14.5 + "@babel/helper-plugin-utils": ^7.12.13 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a35192868166fb5a62003a56ce2c266f74ae680f1d9589652c4495145240dd138a9505301bb5adca069cb874d6f0f733dc2f3d1d05f71a06019735c29c4d1a11 + checksum: 24f34b196d6342f28d4bad303612d7ff566ab0a013ce89e775d98d6f832969462e7235f3e7eaf17678a533d4be0ba45d3ae34ab4e5a9dcbda5d98d49e5efa2fc languageName: node linkType: hard -"@babel/plugin-proposal-optional-catch-binding@npm:^7.14.5, @babel/plugin-proposal-optional-catch-binding@npm:^7.8.3": +"@babel/plugin-syntax-class-static-block@npm:^7.14.5": version: 7.14.5 - resolution: "@babel/plugin-proposal-optional-catch-binding@npm:7.14.5" + resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" dependencies: "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f9c1b2b34fef1bde85feeb0b438131f526056161e10b6fb91c74a5828ad39d2a20521b5c3cefc7367a7e5fc792b7c7e607bf278d7999b5d89824c34af3174eae + checksum: 3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948 languageName: node linkType: hard -"@babel/plugin-proposal-optional-chaining@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/plugin-proposal-optional-chaining@npm:7.9.0" +"@babel/plugin-syntax-decorators@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-decorators@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-syntax-optional-chaining": ^7.8.0 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: da2d4cbf6fe1b3579c83b83cd6b7deb1fa4f907b53eceed8906cf60b0ed02f3dde01bb891040dea67e316865bb8c890ca3272a422d359d2d0a7826c7250572d3 + checksum: 5933fdb1d8d2c0b4b80621ad65dacd4e1ccd836041557c2ddc4cb4c1f46a347fa72977fc519695a801c9cca8b9aaf90d7895ddd52cb4e510fbef5b9f03cb9568 languageName: node linkType: hard -"@babel/plugin-proposal-optional-chaining@npm:^7.14.5, @babel/plugin-proposal-optional-chaining@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-proposal-optional-chaining@npm:7.14.5" +"@babel/plugin-syntax-dynamic-import@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.14.5 - "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/helper-plugin-utils": ^7.8.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9e39e20d162bea2241b4c24ea8a339f872a04954a5155c606bf2437edaa1a15b8a517daee4b2b09cfd42d826b93c57f080aa9fbb13c60a8f3a7a72963badf2df + checksum: ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd languageName: node linkType: hard -"@babel/plugin-proposal-private-methods@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-private-methods@npm:7.14.5" - dependencies: - "@babel/helper-create-class-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: badacc1d68c8cf92a7ba973e3c283bc3aebf586a6573b6d18a96461ce18039d4cdc0135edac1b810df8d92cfca628115d98a0ad83ed8f15bf15eaff21539bf32 - languageName: node - linkType: hard - -"@babel/plugin-proposal-private-property-in-object@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-proposal-private-property-in-object@npm:7.14.5" - dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-create-class-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-private-property-in-object": ^7.14.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: a11da6a52eb13d6dcb6ed36993a81e9746404f6e83d32be16142911b7e5768293d8c4c5373d182ef25cb94d0b18c0c27a07f4553be042ee2dc49f7179f8cbfe2 - languageName: node - linkType: hard - -"@babel/plugin-proposal-unicode-property-regex@npm:^7.14.5, @babel/plugin-proposal-unicode-property-regex@npm:^7.4.4, @babel/plugin-proposal-unicode-property-regex@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-proposal-unicode-property-regex@npm:7.14.5" - dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 58bd3277a972a33d101d29ab4f52e964b6e8ec218eb84f764b4ea67bf8ed362909760812d3f7451ee5e54dc273bd81bc5a00cd2c13e8fb64a47ec117cb69d51b - languageName: node - linkType: hard - -"@babel/plugin-syntax-async-generators@npm:^7.8.0, @babel/plugin-syntax-async-generators@npm:^7.8.4": - version: 7.8.4 - resolution: "@babel/plugin-syntax-async-generators@npm:7.8.4" - dependencies: - "@babel/helper-plugin-utils": ^7.8.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 7ed1c1d9b9e5b64ef028ea5e755c0be2d4e5e4e3d6cf7df757b9a8c4cfa4193d268176d0f1f7fbecdda6fe722885c7fda681f480f3741d8a2d26854736f05367 - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-properties@npm:^7.12.13": - version: 7.12.13 - resolution: "@babel/plugin-syntax-class-properties@npm:7.12.13" - dependencies: - "@babel/helper-plugin-utils": ^7.12.13 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 24f34b196d6342f28d4bad303612d7ff566ab0a013ce89e775d98d6f832969462e7235f3e7eaf17678a533d4be0ba45d3ae34ab4e5a9dcbda5d98d49e5efa2fc - languageName: node - linkType: hard - -"@babel/plugin-syntax-class-static-block@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-class-static-block@npm:7.14.5" +"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": + version: 7.8.3 + resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3e80814b5b6d4fe17826093918680a351c2d34398a914ce6e55d8083d72a9bdde4fbaf6a2dcea0e23a03de26dc2917ae3efd603d27099e2b98380345703bf948 + checksum: 85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a languageName: node linkType: hard -"@babel/plugin-syntax-decorators@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-syntax-decorators@npm:7.14.5" +"@babel/plugin-syntax-flow@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-flow@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7e725deeba3848e8e1b57bc8a74c1a852aa253b9ffd293aa0bc043b93e1e7b669414caae3d20c653d2fab907a9388e526f2138e3783b22e49272098566cf9734 + checksum: 87dfe32f3a3ea77941034fb2a39fdfc9ea18a994b8df40c3659a11c8787b2bc5adea029259c4eafc03cd35f11628f6533aa2a06381db7fcbe3b2cc3c2a2bb54f languageName: node linkType: hard -"@babel/plugin-syntax-dynamic-import@npm:^7.8.0, @babel/plugin-syntax-dynamic-import@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-dynamic-import@npm:7.8.3" +"@babel/plugin-syntax-import-assertions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-import-assertions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.0 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ce307af83cf433d4ec42932329fad25fa73138ab39c7436882ea28742e1c0066626d224e0ad2988724c82644e41601cef607b36194f695cb78a1fcdc959637bd + checksum: 2a463928a63b62052e9fb8f8b0018aa11a926e94f32c168260ae012afe864875c6176c6eb361e13f300542c31316dad791b08a5b8ed92436a3095c7a0e4fce65 languageName: node linkType: hard -"@babel/plugin-syntax-export-namespace-from@npm:^7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-syntax-export-namespace-from@npm:7.8.3" +"@babel/plugin-syntax-import-attributes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-import-attributes@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 85740478be5b0de185228e7814451d74ab8ce0a26fcca7613955262a26e99e8e15e9da58f60c754b84515d4c679b590dbd3f2148f0f58025f4ae706f1c5a5d4a + checksum: 87c8aa4a5ef931313f956871b27f2c051556f627b97ed21e9a5890ca4906b222d89062a956cde459816f5e0dec185ff128d7243d3fdc389504522acb88f0464e languageName: node linkType: hard -"@babel/plugin-syntax-flow@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-syntax-flow@npm:7.14.5" +"@babel/plugin-syntax-import-meta@npm:^7.10.4, @babel/plugin-syntax-import-meta@npm:^7.8.3": + version: 7.10.4 + resolution: "@babel/plugin-syntax-import-meta@npm:7.10.4" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ba6c81325930283bed75c59f92bd7f5873beb006e35fdb092f62498d1f1ecb90f3eaa3d586400ad48dd6d03c63d2bf59a72998e431bab2bd20b3137bd2b10ac0 + checksum: 166ac1125d10b9c0c430e4156249a13858c0366d38844883d75d27389621ebe651115cb2ceb6dc011534d5055719fa1727b59f39e1ab3ca97820eef3dcab5b9b languageName: node linkType: hard -"@babel/plugin-syntax-json-strings@npm:^7.8.0, @babel/plugin-syntax-json-strings@npm:^7.8.3": +"@babel/plugin-syntax-json-strings@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-json-strings@npm:7.8.3" dependencies: @@ -915,18 +859,18 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-jsx@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-jsx@npm:7.14.5" +"@babel/plugin-syntax-jsx@npm:^7.23.3, @babel/plugin-syntax-jsx@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-jsx@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3a2ba87534b0f9ee70eba0754d2ae544825c25afd98efb8e42b41399e02de4cc5b1f70fc5ce444fb7a7e5b09972c289eed2f00917be5b88d67407f4cbde8e960 + checksum: 712f7e7918cb679f106769f57cfab0bc99b311032665c428b98f4c3e2e6d567601d45386a4f246df6a80d741e1f94192b3f008800d66c4f1daae3ad825c243f0 languageName: node linkType: hard -"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4": +"@babel/plugin-syntax-logical-assignment-operators@npm:^7.10.4, @babel/plugin-syntax-logical-assignment-operators@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-logical-assignment-operators@npm:7.10.4" dependencies: @@ -937,7 +881,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.0, @babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": +"@babel/plugin-syntax-nullish-coalescing-operator@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-nullish-coalescing-operator@npm:7.8.3" dependencies: @@ -948,7 +892,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.0, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": +"@babel/plugin-syntax-numeric-separator@npm:^7.10.4, @babel/plugin-syntax-numeric-separator@npm:^7.8.3": version: 7.10.4 resolution: "@babel/plugin-syntax-numeric-separator@npm:7.10.4" dependencies: @@ -959,7 +903,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-object-rest-spread@npm:^7.0.0, @babel/plugin-syntax-object-rest-spread@npm:^7.8.0, @babel/plugin-syntax-object-rest-spread@npm:^7.8.3": +"@babel/plugin-syntax-object-rest-spread@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-object-rest-spread@npm:7.8.3" dependencies: @@ -970,7 +914,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.0, @babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": +"@babel/plugin-syntax-optional-catch-binding@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-optional-catch-binding@npm:7.8.3" dependencies: @@ -981,7 +925,7 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-optional-chaining@npm:^7.8.0, @babel/plugin-syntax-optional-chaining@npm:^7.8.3": +"@babel/plugin-syntax-optional-chaining@npm:^7.8.3": version: 7.8.3 resolution: "@babel/plugin-syntax-optional-chaining@npm:7.8.3" dependencies: @@ -1014,624 +958,731 @@ __metadata: languageName: node linkType: hard -"@babel/plugin-syntax-typescript@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-syntax-typescript@npm:7.14.5" +"@babel/plugin-syntax-typescript@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-syntax-typescript@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5447d13b31aeeeaa5c2b945e60a598642dedca480f11d3232b0927aeb6a6bb8201a0025f509bc23851da4bf126f69b0522790edbd58f4560f0a4984cabd0d126 + checksum: bf4bd70788d5456b5f75572e47a2e31435c7c4e43609bd4dffd2cc0c7a6cf90aabcf6cd389e351854de9a64412a07d30effef5373251fe8f6a4c9db0c0163bda languageName: node linkType: hard -"@babel/plugin-transform-arrow-functions@npm:^7.14.5, @babel/plugin-transform-arrow-functions@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-arrow-functions@npm:7.14.5" +"@babel/plugin-syntax-unicode-sets-regex@npm:^7.18.6": + version: 7.18.6 + resolution: "@babel/plugin-syntax-unicode-sets-regex@npm:7.18.6" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-create-regexp-features-plugin": ^7.18.6 + "@babel/helper-plugin-utils": ^7.18.6 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: a651d700fe63ff0ddfd7186f4ebc24447ca734f114433139e3c027bc94a900d013cf1ef2e2db8430425ba542e39ae160c3b05f06b59fd4656273a3df97679e9c + languageName: node + linkType: hard + +"@babel/plugin-transform-arrow-functions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-arrow-functions@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 126196ea0107e97f711c0d48d8d1e01a30f5a5e127628f7367658b4c5832182c4e28914294408374690c5bfbb4ad4fe6560068d8bf370cafe8d4fe23599aaa95 + checksum: 58f9aa9b0de8382f8cfa3f1f1d40b69d98cd2f52340e2391733d0af745fdddda650ba392e509bc056157c880a2f52834a38ab2c5aa5569af8c61bb6ecbf45f34 languageName: node linkType: hard -"@babel/plugin-transform-async-to-generator@npm:^7.14.5, @babel/plugin-transform-async-to-generator@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-async-to-generator@npm:7.14.5" +"@babel/plugin-transform-async-generator-functions@npm:^7.24.3": + version: 7.24.3 + resolution: "@babel/plugin-transform-async-generator-functions@npm:7.24.3" dependencies: - "@babel/helper-module-imports": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-remap-async-to-generator": ^7.14.5 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-remap-async-to-generator": ^7.22.20 + "@babel/plugin-syntax-async-generators": ^7.8.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4c47016c5f65adaa5836054fcc99402f1d295aedd7ebd44e6df128a90977952f2a8abdf3b3d0aa5a9e1186184da538452c4d9a3b1482376759c6962627201da5 + checksum: 309af02610be65d937664435adb432a32d9b6eb42bb3d3232c377d27fbc57014774d931665a5bfdaff3d1841b72659e0ad7adcef84b709f251cb0b8444f19214 languageName: node linkType: hard -"@babel/plugin-transform-block-scoped-functions@npm:^7.14.5, @babel/plugin-transform-block-scoped-functions@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.14.5" +"@babel/plugin-transform-async-to-generator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-async-to-generator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-module-imports": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-remap-async-to-generator": ^7.22.20 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 9994d9f107308b21be043de115fe1d06956807d93a3039ddab54333d1fbb39ad50cc5f9eccaedf5317f4699230e923662254974f3a974c4f000e986837bc020a + checksum: 429004a6596aa5c9e707b604156f49a146f8d029e31a3152b1649c0b56425264fda5fd38e5db1ddaeb33c3fe45c97dc8078d7abfafe3542a979b49f229801135 languageName: node linkType: hard -"@babel/plugin-transform-block-scoping@npm:^7.14.5, @babel/plugin-transform-block-scoping@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-block-scoping@npm:7.14.5" +"@babel/plugin-transform-block-scoped-functions@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-block-scoped-functions@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d317d636d0475317302e9c8b01cf9214fac3ff9353b23d0d16285f196f5c7b95b7864a8e8eaf51a3e1b650649203855f80a58b7a2caef4b0ee9793e7349a0ec5 + checksum: d8e18bd57b156da1cd4d3c1780ab9ea03afed56c6824ca8e6e74f67959d7989a0e953ec370fe9b417759314f2eef30c8c437395ce63ada2e26c2f469e4704f82 languageName: node linkType: hard -"@babel/plugin-transform-classes@npm:^7.14.5, @babel/plugin-transform-classes@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-classes@npm:7.14.5" +"@babel/plugin-transform-block-scoping@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-transform-block-scoping@npm:7.24.4" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-function-name": ^7.14.5 - "@babel/helper-optimise-call-expression": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-replace-supers": ^7.14.5 - "@babel/helper-split-export-declaration": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 5229ffe1c55744b96f791521e2876b01ed05c81df67488a7453ce66c2faceb9d1d653089ce6f0abf512752e15e9acac0e75a797a860f24e05b4d36497c7c3183 + languageName: node + linkType: hard + +"@babel/plugin-transform-class-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-class-properties@npm:7.24.1" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 95779e9eef0c0638b9631c297d48aee53ffdbb2b1b5221bf40d7eccd566a8e34f859ff3571f8f20b9159b67f1bff7d7dc81da191c15d69fbae5a645197eae7e0 + languageName: node + linkType: hard + +"@babel/plugin-transform-class-static-block@npm:^7.24.4": + version: 7.24.4 + resolution: "@babel/plugin-transform-class-static-block@npm:7.24.4" + dependencies: + "@babel/helper-create-class-features-plugin": ^7.24.4 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-class-static-block": ^7.14.5 + peerDependencies: + "@babel/core": ^7.12.0 + checksum: 3b1db3308b57ba21d47772a9f183804234c23fd64c9ca40915d2d65c5dc7a48b49a6de16b8b90b7a354eacbb51232a862f0fca3dbd23e27d34641f511decddab + languageName: node + linkType: hard + +"@babel/plugin-transform-classes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-classes@npm:7.24.1" + dependencies: + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-environment-visitor": ^7.22.20 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-replace-supers": ^7.24.1 + "@babel/helper-split-export-declaration": ^7.22.6 globals: ^11.1.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 42fc333a0d8a6a90b5c75e90d2ec21494f711ab7c58f2d074d95726cdd38f137e74653602a82d2d1a3e9bc504b5eff62418d70048514b672c9bd108bfb866e25 + checksum: e5337e707d731c9f4dcc107d09c9a99b90786bc0da6a250165919587ed818818f6cae2bbcceea880abef975c0411715c0c7f3f361ecd1526bf2eaca5ad26bb00 languageName: node linkType: hard -"@babel/plugin-transform-computed-properties@npm:^7.14.5, @babel/plugin-transform-computed-properties@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-computed-properties@npm:7.14.5" +"@babel/plugin-transform-computed-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-computed-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/template": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 87bd4c46255359ab8d53d0e9b5aa5e1ef218c1447874bd8c2eff759d3a2b5fe6b3ec55046babe0087f7e3890f6167524c729737e912080ea1c9758a559765130 + checksum: f2832bcf100a70f348facbb395873318ef5b9ee4b0fb4104a420d9daaeb6003cc2ecc12fd8083dd2e4a7c2da873272ad73ff94de4497125a0cf473294ef9664e languageName: node linkType: hard -"@babel/plugin-transform-destructuring@npm:^7.14.7, @babel/plugin-transform-destructuring@npm:^7.8.3": - version: 7.14.7 - resolution: "@babel/plugin-transform-destructuring@npm:7.14.7" +"@babel/plugin-transform-destructuring@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-destructuring@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 0b0cf8ed9fb92c53e3888c17402c4f1e8f329f05a759829b559df883b19b442d3950b7f319df419d0cff122ea76fc8b3b55779fdbb9e394e5f058419a8d5ba14 + checksum: 994fd3c513e40b8f1bdfdd7104ebdcef7c6a11a4e380086074496f586db3ac04cba0ae70babb820df6363b6700747b0556f6860783e046ace7c741a22f49ec5b languageName: node linkType: hard -"@babel/plugin-transform-dotall-regex@npm:^7.14.5, @babel/plugin-transform-dotall-regex@npm:^7.4.4, @babel/plugin-transform-dotall-regex@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-dotall-regex@npm:7.14.5" +"@babel/plugin-transform-dotall-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-dotall-regex@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4da3dac9580823c1fe8aaedf6109d3a26d17ad7ef7d1b278ddbcd7c148e02c465cf49250794529a34bac0bda6b53db558ae08d185a96b76efaaa17a5da3911df + checksum: 7f623d25b6f213b94ebc1754e9e31c1077c8e288626d8b7bfa76a97b067ce80ddcd0ede402a546706c65002c0ccf45cd5ec621511c2668eed31ebcabe8391d35 languageName: node linkType: hard -"@babel/plugin-transform-duplicate-keys@npm:^7.14.5, @babel/plugin-transform-duplicate-keys@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-duplicate-keys@npm:7.14.5" +"@babel/plugin-transform-duplicate-keys@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-duplicate-keys@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: c6c951d2f7ed528a8103d08293d4aaf95efa38c697e7b2b27b7e6c9780280484373e2f7ef8d77daf17dffdc86748fbf75e776e0542b1c7b17e29308bc31ebd8c + checksum: a3b07c07cee441e185858a9bb9739bb72643173c18bf5f9f949dd2d4784ca124e56b01d0a270790fb1ff0cf75d436075db0a2b643fb4285ff9a21df9e8dc6284 languageName: node linkType: hard -"@babel/plugin-transform-exponentiation-operator@npm:^7.14.5, @babel/plugin-transform-exponentiation-operator@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.14.5" +"@babel/plugin-transform-dynamic-import@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-dynamic-import@npm:7.24.1" dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-dynamic-import": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7588a582d0bc5c80fda7f1c631354a35a9a7d284dd80ccaf2bbfd086a39a9d6461718dc7dd45a3ca59228593270a7c6a907a9cbe7ddc349d80c7342af0263c5c + checksum: 59fc561ee40b1a69f969c12c6c5fac206226d6642213985a569dd0f99f8e41c0f4eaedebd36936c255444a8335079842274c42a975a433beadb436d4c5abb79b languageName: node linkType: hard -"@babel/plugin-transform-flow-strip-types@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/plugin-transform-flow-strip-types@npm:7.9.0" +"@babel/plugin-transform-exponentiation-operator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-exponentiation-operator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-syntax-flow": ^7.8.3 + "@babel/helper-builder-binary-assignment-operator-visitor": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4bc74b721db01e91c6d591f927b53fa509d69d5c49911f31d9202df984cf2eda8397346826647cb660f72676dd3e5a2498187f587e7e181c0ca66b28b1252591 + checksum: f90841fe1a1e9f680b4209121d3e2992f923e85efcd322b26e5901c180ef44ff727fb89790803a23fac49af34c1ce2e480018027c22b4573b615512ac5b6fc50 languageName: node linkType: hard -"@babel/plugin-transform-for-of@npm:^7.14.5, @babel/plugin-transform-for-of@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-for-of@npm:7.14.5" +"@babel/plugin-transform-export-namespace-from@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-export-namespace-from@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-export-namespace-from": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: aeb76eb11d10b2390996001e2fd529bbaf3695edd306d24e4eba87b8137c10a6afda3896017f88fcf40fd2334cc424c0a111fad34e10c747e81e577e5957e328 + checksum: bc710ac231919df9555331885748385c11c5e695d7271824fe56fba51dd637d48d3e5cd52e1c69f2b1a384fbbb41552572bc1ca3a2285ee29571f002e9bb2421 languageName: node linkType: hard -"@babel/plugin-transform-function-name@npm:^7.14.5, @babel/plugin-transform-function-name@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-function-name@npm:7.14.5" +"@babel/plugin-transform-flow-strip-types@npm:^7.16.0": + version: 7.24.1 + resolution: "@babel/plugin-transform-flow-strip-types@npm:7.24.1" dependencies: - "@babel/helper-function-name": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-flow": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3db2fa1bcd21b76a91ce78db8ebca047fdadbf198f816e2621e531a751a0d40976cf2a25262dee9352fd0c53bff5b25fddefadebdbb4ba3da6d89b849ab075b6 + checksum: 83faac90c934e15a8fe813d90cbfdf8aa2cb2cc9108f55e4a1ecda1c3097735af6a0b6623057f059153b572bc1dd088aeb2ff24217e9de82ad2390ab1210d01b languageName: node linkType: hard -"@babel/plugin-transform-literals@npm:^7.14.5, @babel/plugin-transform-literals@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-literals@npm:7.14.5" +"@babel/plugin-transform-for-of@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-for-of@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2341cfaaf8ac7199c578407ea4de41205d3d74c5a48899aa96c41b08c09d18c46d9018fdc6a2f69f0bccc2662223afc47b60130ae4ff36a79351fface71a61f3 + checksum: 990adde96ea1766ed6008c006c7040127bef59066533bb2977b246ea4a596fe450a528d1881a0db5f894deaf1b81654dfb494b19ad405b369be942738aa9c364 languageName: node linkType: hard -"@babel/plugin-transform-member-expression-literals@npm:^7.14.5, @babel/plugin-transform-member-expression-literals@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-member-expression-literals@npm:7.14.5" +"@babel/plugin-transform-function-name@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-function-name@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-function-name": ^7.23.0 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: a94ff910e8d0e28effd58c64f2d15c9772ea4c209644f116fd81dc5c93ce232304f42ef14d5ec2baf095c824786698fcf6c1d4c91952dc3762350f4ec0eb1f17 + checksum: 31eb3c75297dda7265f78eba627c446f2324e30ec0124a645ccc3e9f341254aaa40d6787bd62b2280d77c0a5c9fbfce1da2c200ef7c7f8e0a1b16a8eb3644c6f languageName: node linkType: hard -"@babel/plugin-transform-modules-amd@npm:^7.14.5, @babel/plugin-transform-modules-amd@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-modules-amd@npm:7.14.5" +"@babel/plugin-transform-json-strings@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-json-strings@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - babel-plugin-dynamic-import-node: ^2.3.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-json-strings": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 963d9ebb11b282d5c5f462e3e1ad6991e60fb4d190b5a7aa0d9937e0fa83d89cf5f94268f0b0b343576f2cee0cf545bcaf40da40eb8b9dca5c79840fd86a65ed + checksum: f42302d42fc81ac00d14e9e5d80405eb80477d7f9039d7208e712d6bcd486a4e3b32fdfa07b5f027d6c773723d8168193ee880f93b0e430c828e45f104fb82a4 languageName: node linkType: hard -"@babel/plugin-transform-modules-commonjs@npm:^7.14.5, @babel/plugin-transform-modules-commonjs@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-modules-commonjs@npm:7.14.5" +"@babel/plugin-transform-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-literals@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-simple-access": ^7.14.5 - babel-plugin-dynamic-import-node: ^2.3.3 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5cc41ee904e421c32f692ce10985190bc8f995df63ee1fd899ea80ce50b4b8408c7f2fddf16e01345244fc5702c8b9c0772afdd934e325c4e468840daa9bee04 + checksum: 2df94e9478571852483aca7588419e574d76bde97583e78551c286f498e01321e7dbb1d0ef67bee16e8f950688f79688809cfde370c5c4b84c14d841a3ef217a languageName: node linkType: hard -"@babel/plugin-transform-modules-systemjs@npm:^7.14.5, @babel/plugin-transform-modules-systemjs@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-modules-systemjs@npm:7.14.5" +"@babel/plugin-transform-logical-assignment-operators@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-logical-assignment-operators@npm:7.24.1" dependencies: - "@babel/helper-hoist-variables": ^7.14.5 - "@babel/helper-module-transforms": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-validator-identifier": ^7.14.5 - babel-plugin-dynamic-import-node: ^2.3.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3ca0bb1c0c22a3d705476186afa9fc86398ae4662afc259ff29c1942e3c8770f4bdadaf67418a21816964d4e1eaf07412eeabccccfaa9d45eac735f971ad148b + checksum: 895f2290adf457cbf327428bdb4fb90882a38a22f729bcf0629e8ad66b9b616d2721fbef488ac00411b647489d1dda1d20171bb3772d0796bb7ef5ecf057808a languageName: node linkType: hard -"@babel/plugin-transform-modules-umd@npm:^7.14.5, @babel/plugin-transform-modules-umd@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-modules-umd@npm:7.14.5" +"@babel/plugin-transform-member-expression-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-member-expression-literals@npm:7.24.1" dependencies: - "@babel/helper-module-transforms": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 455ff383bed47e104d4b2b32f11bc5a44a25c797fad26b5eab9b8a81856f9945350b45ad28b9b20b0bbf324832c7a826c9c3d6f865e85c26a1771663132e4145 + checksum: 4ea641cc14a615f9084e45ad2319f95e2fee01c77ec9789685e7e11a6c286238a426a98f9c1ed91568a047d8ac834393e06e8c82d1ff01764b7aa61bee8e9023 languageName: node linkType: hard -"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.14.7, @babel/plugin-transform-named-capturing-groups-regex@npm:^7.8.3": - version: 7.14.7 - resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.14.7" +"@babel/plugin-transform-modules-amd@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-amd@npm:7.24.1" + dependencies: + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 3d777c262f257e93f0405b13e178f9c4a0f31855b409f0191a76bb562a28c541326a027bfe6467fcb74752f3488c0333b5ff2de64feec1b3c4c6ace1747afa03 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-commonjs@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-commonjs@npm:7.24.1" + dependencies: + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-simple-access": ^7.22.5 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 11402b34c49f76aa921b43c2d76f3f129a32544a1dc4f0d1e48b310f9036ab75269a6d8684ed0198b7a0b07bd7898b12f0cacceb26fbb167999fd2a819aa0802 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-systemjs@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-systemjs@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.14.5 + "@babel/helper-hoist-variables": ^7.22.5 + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-identifier": ^7.22.20 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 903766f6808f04278e887e4adec9b1efa741726279652dad255eaad0f5701df8f8ff0af25eb8541a00eb3c9eae2dccf337b085cfa011426ca33ed1f95d70bf75 + languageName: node + linkType: hard + +"@babel/plugin-transform-modules-umd@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-modules-umd@npm:7.24.1" + dependencies: + "@babel/helper-module-transforms": ^7.23.3 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 4922f5056d34de6fd59a1ab1c85bc3472afa706c776aceeb886289c9ac9117e6eb8e22d06c537eb5bc0ede6c30f6bd85210bdcc150dc0ae2d2373f8252df9364 + languageName: node + linkType: hard + +"@babel/plugin-transform-named-capturing-groups-regex@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-named-capturing-groups-regex@npm:7.22.5" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.22.5 + "@babel/helper-plugin-utils": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0 - checksum: 3c68bc77cce387750ecd32d33e9ad0f0968245fbe03b36ec8dddc52bee3ee84757205db3b3b4fc605e055f08769312ef4dbf4a0c8adb8f02eb04b142ffcdf265 + checksum: 3ee564ddee620c035b928fdc942c5d17e9c4b98329b76f9cefac65c111135d925eb94ed324064cd7556d4f5123beec79abea1d4b97d1c8a2a5c748887a2eb623 languageName: node linkType: hard -"@babel/plugin-transform-new-target@npm:^7.14.5, @babel/plugin-transform-new-target@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-new-target@npm:7.14.5" +"@babel/plugin-transform-new-target@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-new-target@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5b806c86926cd0b03fa2f22cf21a6d6a86e5831b80e8a1e898877acd3a03fd07078e45da33b671200ec98a5c7ac9be2f3592cd88933e262feffba248ca7ca4e7 + checksum: f56159ba56e8824840b8073f65073434e4bc4ef20e366bc03aa6cae9a4389365574fa72390e48aed76049edbc6eba1181eb810e58fae22c25946c62f9da13db4 languageName: node linkType: hard -"@babel/plugin-transform-object-super@npm:^7.14.5, @babel/plugin-transform-object-super@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-object-super@npm:7.14.5" +"@babel/plugin-transform-nullish-coalescing-operator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-nullish-coalescing-operator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-replace-supers": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 88477a8b27e76042ffbff1345088422f5b3135346d69f264e71d90b3749a3d73d5a579c97a33cd11c61c5d499a655911c7cd97dbe68edb36e090dfd5f154d777 + checksum: 74025e191ceb7cefc619c15d33753aab81300a03d81b96ae249d9b599bc65878f962d608f452462d3aad5d6e334b7ab2b09a6bdcfe8d101fe77ac7aacca4261e languageName: node linkType: hard -"@babel/plugin-transform-parameters@npm:^7.14.5, @babel/plugin-transform-parameters@npm:^7.8.7": - version: 7.14.5 - resolution: "@babel/plugin-transform-parameters@npm:7.14.5" +"@babel/plugin-transform-numeric-separator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-numeric-separator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-numeric-separator": ^7.10.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 932bc616be7b5542ba2371c85cfcc579a8556b9e5a5ea5535b7f0ec5b68284ed2a3724ae181f1a22719b5ea6539c82f5fcee37d9f45f08ed72eb9e43a0940b56 + checksum: 3247bd7d409574fc06c59e0eb573ae7470d6d61ecf780df40b550102bb4406747d8f39dcbec57eb59406df6c565a86edd3b429e396ad02e4ce201ad92050832e languageName: node linkType: hard -"@babel/plugin-transform-property-literals@npm:^7.14.5, @babel/plugin-transform-property-literals@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-property-literals@npm:7.14.5" +"@babel/plugin-transform-object-rest-spread@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-object-rest-spread@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-transform-parameters": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 426e7b13a048220314e35bd4e6732640293c616173ef05ceca3a2bfadd043199e35ec693f1604f77178c3a88bea241b6d7ce92d8fc837faeb37117ad7866350f + checksum: d5d28b1f33c279a38299d34011421a4915e24b3846aa23a1aba947f1366ce673ddf8df09dd915e0f2c90c5327f798bf126dca013f8adff1fc8f09e18878b675a languageName: node linkType: hard -"@babel/plugin-transform-react-constant-elements@npm:^7.0.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-constant-elements@npm:7.14.5" +"@babel/plugin-transform-object-super@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-object-super@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-replace-supers": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 7e4168535cd3ae1bae5acf8d7cc77a2bd885f8abed46672160631e23ded0c7e0be5152cefb1f87b123c4e3c38a542ca0ce06b3b0d8e7b7694f43687b63c0a9fb + checksum: d34d437456a54e2a5dcb26e9cf09ed4c55528f2a327c5edca92c93e9483c37176e228d00d6e0cf767f3d6fdbef45ae3a5d034a7c59337a009e20ae541c8220fa languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:7.8.3": - version: 7.8.3 - resolution: "@babel/plugin-transform-react-display-name@npm:7.8.3" +"@babel/plugin-transform-optional-catch-binding@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-optional-catch-binding@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2712345cdf6aa62ca4da3e749a247c99210658cd3c22ad7579052fb451ca6af482d4dee77ae295c3d12efc603aa0ee4a00399347d8e8ad962aa8715037a17e8e + checksum: ff7c02449d32a6de41e003abb38537b4a1ad90b1eaa4c0b578cb1b55548201a677588a8c47f3e161c72738400ae811a6673ea7b8a734344755016ca0ac445dac languageName: node linkType: hard -"@babel/plugin-transform-react-display-name@npm:^7.14.5, @babel/plugin-transform-react-display-name@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-display-name@npm:7.14.5" +"@babel/plugin-transform-optional-chaining@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-optional-chaining@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: d7ca35d5e8d7d91ac82b17e1bd68dd4a7dcfae54da95b28d072907799503e2ec234f34dd869c9fee299a29e73e7b5ce3d4c748cf2a29c25d39f9523be130dba3 + checksum: 0eb5f4abdeb1a101c0f67ef25eba4cce0978a74d8722f6222cdb179a28e60d21ab545eda231855f50169cd63d604ec8268cff44ae9370fd3a499a507c56c2bbd languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-development@npm:^7.14.5, @babel/plugin-transform-react-jsx-development@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-jsx-development@npm:7.14.5" +"@babel/plugin-transform-parameters@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-parameters@npm:7.24.1" dependencies: - "@babel/plugin-transform-react-jsx": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b49d6e703aeb4fbaacbb8449418dc3c599bcb3ce608cb900ed21a288c3bce42a33209524693b1978766b645aa2b751c15aa9da5337cc6ac2a79fd9b7c9ae9246 + checksum: d183008e67b1a13b86c92fb64327a75cd8e13c13eb80d0b6952e15806f1b0c4c456d18360e451c6af73485b2c8f543608b0a29e5126c64eb625a31e970b65f80 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-self@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-jsx-self@npm:7.14.5" +"@babel/plugin-transform-private-methods@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-private-methods@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: b1b19d3aa0d383fd06e085bcb5462a310dd844a073cc608115a3582ed88ca23d1511dc75cfa81369c2a254e14428b0e6482e6c48bdef346764d801882de8012f + checksum: 7208c30bb3f3fbc73fb3a88bdcb78cd5cddaf6d523eb9d67c0c04e78f6fc6319ece89f4a5abc41777ceab16df55b3a13a4120e0efc9275ca6d2d89beaba80aa0 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx-source@npm:^7.9.0": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-jsx-source@npm:7.14.5" +"@babel/plugin-transform-private-property-in-object@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-private-property-in-object@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.24.1 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-private-property-in-object": ^7.14.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: e7e7336bbd07d6c1a281bac1b242e8cb8172f3b1e1d9d214160ab220142fbefc5d79786d57bf197b18f4c694edfc7614dddae2f990adb4b7484146635b58dfe6 + checksum: 47c123ca9975f7f6b20e6fe8fe89f621cd04b622539faf5ec037e2be7c3d53ce2506f7c785b1930dcdea11994eff79094a02715795218c7d6a0bdc11f2fb3ac2 languageName: node linkType: hard -"@babel/plugin-transform-react-jsx@npm:^7.14.5, @babel/plugin-transform-react-jsx@npm:^7.9.1": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-jsx@npm:7.14.5" +"@babel/plugin-transform-property-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-property-literals@npm:7.24.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-module-imports": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-jsx": ^7.14.5 - "@babel/types": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 4be6ba0a0303691ce7e16363da1ae446a5cd6eb63ba5729cd7af21b0e7927c07bb8595482836cbda0f41b39fa979c37f4504ef7c23729085f84fac1659615542 + checksum: a73646d7ecd95b3931a3ead82c7d5efeb46e68ba362de63eb437d33531f294ec18bd31b6d24238cd3b6a3b919a6310c4a0ba4a2629927721d4d10b0518eb7715 languageName: node linkType: hard -"@babel/plugin-transform-react-pure-annotations@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.14.5" +"@babel/plugin-transform-react-constant-elements@npm:^7.9.0": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-constant-elements@npm:7.24.1" dependencies: - "@babel/helper-annotate-as-pure": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 3b62cc6af2c838eabc28c07473eab1392b41a5db2f0f326b1ba3ec52b95529e1c46098d6a259c7debb6a17489445828b89f7737a6fb85345ea5d27e4819a31fe + checksum: 37fd10113b786a2462cf15366aa3a11a2a5bdba9bf8881b2544941f5ad6175ebc31116be5a53549c9fce56a08ded6e0b57adb45d6e42efb55d3bc0ff7afdd433 languageName: node linkType: hard -"@babel/plugin-transform-regenerator@npm:^7.14.5, @babel/plugin-transform-regenerator@npm:^7.8.7": - version: 7.14.5 - resolution: "@babel/plugin-transform-regenerator@npm:7.14.5" +"@babel/plugin-transform-react-display-name@npm:^7.16.0, @babel/plugin-transform-react-display-name@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-display-name@npm:7.24.1" dependencies: - regenerator-transform: ^0.14.2 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: f606bc04da7d0cfd651914cb144e85a0ea6fe20ee453ed21d002747cc47b09c853bc97166c32dc47e959581b772d9883f7d96d1c8e795c81ed21dbbb300e3aa7 + checksum: d87ac36073f923a25de0ed3cffac067ec5abc4cde63f7f4366881388fbea6dcbced0e4fefd3b7e99edfe58a4ce32ea4d4c523a577d2b9f0515b872ed02b3d8c3 languageName: node linkType: hard -"@babel/plugin-transform-reserved-words@npm:^7.14.5, @babel/plugin-transform-reserved-words@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-reserved-words@npm:7.14.5" +"@babel/plugin-transform-react-jsx-development@npm:^7.22.5": + version: 7.22.5 + resolution: "@babel/plugin-transform-react-jsx-development@npm:7.22.5" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/plugin-transform-react-jsx": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 8a40d7b48e1b4a549272d603e7b28ead70213e12353d65edd07156b7169d7933cee8b79987b54f374f3c41b835d941aca4b13b8aa23a922c94113af2131ca686 + checksum: 36bc3ff0b96bb0ef4723070a50cfdf2e72cfd903a59eba448f9fe92fea47574d6f22efd99364413719e1f3fb3c51b6c9b2990b87af088f8486a84b2a5f9e4560 languageName: node linkType: hard -"@babel/plugin-transform-runtime@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/plugin-transform-runtime@npm:7.9.0" +"@babel/plugin-transform-react-jsx@npm:^7.22.5, @babel/plugin-transform-react-jsx@npm:^7.23.4": + version: 7.23.4 + resolution: "@babel/plugin-transform-react-jsx@npm:7.23.4" dependencies: - "@babel/helper-module-imports": ^7.8.3 - "@babel/helper-plugin-utils": ^7.8.3 - resolve: ^1.8.1 - semver: ^5.5.1 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-module-imports": ^7.22.15 + "@babel/helper-plugin-utils": ^7.22.5 + "@babel/plugin-syntax-jsx": ^7.23.3 + "@babel/types": ^7.23.4 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 48d6a6ada6bb0a08179ab23e7b63b7e5430abb1a6b21f3979524c5574cd0de033abe196c4ec0ff4470a13b87ee367acf4b21ed0ae9294659ee530b89278786fd + checksum: d8b8c52e8e22e833bf77c8d1a53b0a57d1fd52ba9596a319d572de79446a8ed9d95521035bc1175c1589d1a6a34600d2e678fa81d81bac8fac121137097f1f0a languageName: node linkType: hard -"@babel/plugin-transform-shorthand-properties@npm:^7.14.5, @babel/plugin-transform-shorthand-properties@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-shorthand-properties@npm:7.14.5" +"@babel/plugin-transform-react-pure-annotations@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-react-pure-annotations@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 60cdd17e347a6a0973c8ea5c08ae4b3f8e59ce0e188453c4bda045d2a5c34495af8e0e9393631aa9f3fd51282455b9c5d6ba07e262576171dbe2b4094bdaf8ad + checksum: 06a6bfe80f1f36408d07dd80c48cf9f61177c8e5d814e80ddbe88cfad81a8b86b3110e1fe9d1ac943db77e74497daa7f874b5490c788707106ad26ecfbe44813 languageName: node linkType: hard -"@babel/plugin-transform-spread@npm:^7.14.6, @babel/plugin-transform-spread@npm:^7.8.3": - version: 7.14.6 - resolution: "@babel/plugin-transform-spread@npm:7.14.6" +"@babel/plugin-transform-regenerator@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-regenerator@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-skip-transparent-expression-wrappers": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + regenerator-transform: ^0.15.2 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 20c11de962dd7ddab110d6c4ab9f3c0bea97393ce09cbe4e46be53182c3df0577eaf0e31aaa2d76344ae21ed3a3b7e779fe814b845d188e11a6031c619648b89 + checksum: a04319388a0a7931c3f8e15715d01444c32519692178b70deccc86d53304e74c0f589a4268f6c68578d86f75e934dd1fe6e6ed9071f54ee8379f356f88ef6e42 languageName: node linkType: hard -"@babel/plugin-transform-sticky-regex@npm:^7.14.5, @babel/plugin-transform-sticky-regex@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-sticky-regex@npm:7.14.5" +"@babel/plugin-transform-reserved-words@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-reserved-words@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 6d77e0641c4c72203d592d54fdb11770de22a34d659d3335e4c537e95b930d03142b11f1d41d103da3de063c628a0f34bdd4c6534b591bc59d9ce67fafb836dc + checksum: 132c6040c65aabae2d98a39289efb5c51a8632546dc50d2ad032c8660aec307fbed74ef499856ea4f881fc8505905f49b48e0270585da2ea3d50b75e962afd89 languageName: node linkType: hard -"@babel/plugin-transform-template-literals@npm:^7.14.5, @babel/plugin-transform-template-literals@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-template-literals@npm:7.14.5" +"@babel/plugin-transform-runtime@npm:^7.16.4": + version: 7.24.3 + resolution: "@babel/plugin-transform-runtime@npm:7.24.3" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-module-imports": ^7.24.3 + "@babel/helper-plugin-utils": ^7.24.0 + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.1 + babel-plugin-polyfill-regenerator: ^0.6.1 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 56d273470c16e83bac1bfab5057a64f23191b51460a009b522b3b29806d7a9f64cbd94323836ceb997c4f331b85564f952eb5566c7bd140d0b278f0191a31985 + checksum: 719112524e6fe3e665385ad4425530dadb2ddee839023381ed9d77edf5ce2748f32cc0e38dacda1990c56a7ae0af4de6cdca2413ffaf307e9f75f8d2200d09a2 languageName: node linkType: hard -"@babel/plugin-transform-typeof-symbol@npm:^7.14.5, @babel/plugin-transform-typeof-symbol@npm:^7.8.4": - version: 7.14.5 - resolution: "@babel/plugin-transform-typeof-symbol@npm:7.14.5" +"@babel/plugin-transform-shorthand-properties@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-shorthand-properties@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1e71ec00ea8b64522b8677c030f334cc5b3833a5b7269a152a2ba7a6b36f0e0a4333a61072e69113e4062e71554d4751ef2e3ddd5e81994978123323f266981c + checksum: 006a2032d1c57dca76579ce6598c679c2f20525afef0a36e9d42affe3c8cf33c1427581ad696b519cc75dfee46c5e8ecdf0c6a29ffb14250caa3e16dd68cb424 languageName: node linkType: hard -"@babel/plugin-transform-typescript@npm:^7.9.0": - version: 7.14.6 - resolution: "@babel/plugin-transform-typescript@npm:7.14.6" +"@babel/plugin-transform-spread@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-spread@npm:7.24.1" dependencies: - "@babel/helper-create-class-features-plugin": ^7.14.6 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/plugin-syntax-typescript": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-skip-transparent-expression-wrappers": ^7.22.5 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: cb3117cfc9c8ebf9612b137eb660448e79a876a189fcad6b79641faa7200073bbfd08bf0e63c7ddb3a35b3d31457d6e90cf63565e64446a73866290dc97353fa + checksum: 622ef507e2b5120a9010b25d3df5186c06102ecad8751724a38ec924df8d3527688198fa490c47064eabba14ef2f961b3069855bd22a8c0a1e51a23eed348d02 languageName: node linkType: hard -"@babel/plugin-transform-unicode-escapes@npm:^7.14.5": - version: 7.14.5 - resolution: "@babel/plugin-transform-unicode-escapes@npm:7.14.5" +"@babel/plugin-transform-sticky-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-sticky-regex@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 2a6979c5b886d9c7d9d3887374d75384542fe05a71eb7738b2cde659386089a930d37d1a34ffb4b87def98fbed3526d78b7cd5dd9bffde4d406b368faba81b7d + checksum: e326e96a9eeb6bb01dbc4d3362f989411490671b97f62edf378b8fb102c463a018b777f28da65344d41b22aa6efcdfa01ed43d2b11fdcf202046d3174be137c5 languageName: node linkType: hard -"@babel/plugin-transform-unicode-regex@npm:^7.14.5, @babel/plugin-transform-unicode-regex@npm:^7.8.3": - version: 7.14.5 - resolution: "@babel/plugin-transform-unicode-regex@npm:7.14.5" +"@babel/plugin-transform-template-literals@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-template-literals@npm:7.24.1" dependencies: - "@babel/helper-create-regexp-features-plugin": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 1b7a4c0dc6b07390f991e7cac8409f7a1ae74495d94b9e1fb5a716d5362a349a35717cfad883074e3f80e16bb630bbd1986a3436f739f6b01c30a96ef3f9ea9a + checksum: 4c9009c72321caf20e3b6328bbe9d7057006c5ae57b794cf247a37ca34d87dfec5e27284169a16df5a6235a083bf0f3ab9e1bfcb005d1c8b75b04aed75652621 languageName: node linkType: hard -"@babel/preset-env@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/preset-env@npm:7.9.0" +"@babel/plugin-transform-typeof-symbol@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-typeof-symbol@npm:7.24.1" dependencies: - "@babel/compat-data": ^7.9.0 - "@babel/helper-compilation-targets": ^7.8.7 - "@babel/helper-module-imports": ^7.8.3 - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-proposal-async-generator-functions": ^7.8.3 - "@babel/plugin-proposal-dynamic-import": ^7.8.3 - "@babel/plugin-proposal-json-strings": ^7.8.3 - "@babel/plugin-proposal-nullish-coalescing-operator": ^7.8.3 - "@babel/plugin-proposal-numeric-separator": ^7.8.3 - "@babel/plugin-proposal-object-rest-spread": ^7.9.0 - "@babel/plugin-proposal-optional-catch-binding": ^7.8.3 - "@babel/plugin-proposal-optional-chaining": ^7.9.0 - "@babel/plugin-proposal-unicode-property-regex": ^7.8.3 - "@babel/plugin-syntax-async-generators": ^7.8.0 - "@babel/plugin-syntax-dynamic-import": ^7.8.0 - "@babel/plugin-syntax-json-strings": ^7.8.0 - "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.0 - "@babel/plugin-syntax-numeric-separator": ^7.8.0 - "@babel/plugin-syntax-object-rest-spread": ^7.8.0 - "@babel/plugin-syntax-optional-catch-binding": ^7.8.0 - "@babel/plugin-syntax-optional-chaining": ^7.8.0 - "@babel/plugin-syntax-top-level-await": ^7.8.3 - "@babel/plugin-transform-arrow-functions": ^7.8.3 - "@babel/plugin-transform-async-to-generator": ^7.8.3 - "@babel/plugin-transform-block-scoped-functions": ^7.8.3 - "@babel/plugin-transform-block-scoping": ^7.8.3 - "@babel/plugin-transform-classes": ^7.9.0 - "@babel/plugin-transform-computed-properties": ^7.8.3 - "@babel/plugin-transform-destructuring": ^7.8.3 - "@babel/plugin-transform-dotall-regex": ^7.8.3 - "@babel/plugin-transform-duplicate-keys": ^7.8.3 - "@babel/plugin-transform-exponentiation-operator": ^7.8.3 - "@babel/plugin-transform-for-of": ^7.9.0 - "@babel/plugin-transform-function-name": ^7.8.3 - "@babel/plugin-transform-literals": ^7.8.3 - "@babel/plugin-transform-member-expression-literals": ^7.8.3 - "@babel/plugin-transform-modules-amd": ^7.9.0 - "@babel/plugin-transform-modules-commonjs": ^7.9.0 - "@babel/plugin-transform-modules-systemjs": ^7.9.0 - "@babel/plugin-transform-modules-umd": ^7.9.0 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.8.3 - "@babel/plugin-transform-new-target": ^7.8.3 - "@babel/plugin-transform-object-super": ^7.8.3 - "@babel/plugin-transform-parameters": ^7.8.7 - "@babel/plugin-transform-property-literals": ^7.8.3 - "@babel/plugin-transform-regenerator": ^7.8.7 - "@babel/plugin-transform-reserved-words": ^7.8.3 - "@babel/plugin-transform-shorthand-properties": ^7.8.3 - "@babel/plugin-transform-spread": ^7.8.3 - "@babel/plugin-transform-sticky-regex": ^7.8.3 - "@babel/plugin-transform-template-literals": ^7.8.3 - "@babel/plugin-transform-typeof-symbol": ^7.8.4 - "@babel/plugin-transform-unicode-regex": ^7.8.3 - "@babel/preset-modules": ^0.1.3 - "@babel/types": ^7.9.0 - browserslist: ^4.9.1 - core-js-compat: ^3.6.2 - invariant: ^2.2.2 - levenary: ^1.1.1 - semver: ^5.5.0 + "@babel/helper-plugin-utils": ^7.24.0 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 5578f6163488ed945c7c318402388d742aef91021ed4c080cba87e22975f0e32f0caadb309fe8687f7a44b2ad7153e4b00f69b7b665f2a2ffd6d43732317f877 + checksum: 90251c02986aebe50937522a6e404cb83db1b1feda17c0244e97d6429ded1634340c8411536487d14c54495607e1b7c9dc4db4aed969d519f1ff1e363f9c2229 languageName: node linkType: hard -"@babel/preset-env@npm:^7.4.5": - version: 7.14.7 - resolution: "@babel/preset-env@npm:7.14.7" +"@babel/plugin-transform-typescript@npm:^7.24.1": + version: 7.24.4 + resolution: "@babel/plugin-transform-typescript@npm:7.24.4" dependencies: - "@babel/compat-data": ^7.14.7 - "@babel/helper-compilation-targets": ^7.14.5 - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-validator-option": ^7.14.5 - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.14.5 - "@babel/plugin-proposal-async-generator-functions": ^7.14.7 - "@babel/plugin-proposal-class-properties": ^7.14.5 - "@babel/plugin-proposal-class-static-block": ^7.14.5 - "@babel/plugin-proposal-dynamic-import": ^7.14.5 - "@babel/plugin-proposal-export-namespace-from": ^7.14.5 - "@babel/plugin-proposal-json-strings": ^7.14.5 - "@babel/plugin-proposal-logical-assignment-operators": ^7.14.5 - "@babel/plugin-proposal-nullish-coalescing-operator": ^7.14.5 - "@babel/plugin-proposal-numeric-separator": ^7.14.5 - "@babel/plugin-proposal-object-rest-spread": ^7.14.7 - "@babel/plugin-proposal-optional-catch-binding": ^7.14.5 - "@babel/plugin-proposal-optional-chaining": ^7.14.5 - "@babel/plugin-proposal-private-methods": ^7.14.5 - "@babel/plugin-proposal-private-property-in-object": ^7.14.5 - "@babel/plugin-proposal-unicode-property-regex": ^7.14.5 + "@babel/helper-annotate-as-pure": ^7.22.5 + "@babel/helper-create-class-features-plugin": ^7.24.4 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/plugin-syntax-typescript": ^7.24.1 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 57a9a776b1910c706d28972e4b056ced3af8fc59c29b2a6205c2bb2a408141ddb59a8f2f6041f8467a7b260942818767f4ecabb9f63adf7fddf2afa25e774dfc + languageName: node + linkType: hard + +"@babel/plugin-transform-unicode-escapes@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-escapes@npm:7.24.1" + dependencies: + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: d4d7cfea91af7be2768fb6bed902e00d6e3190bda738b5149c3a788d570e6cf48b974ec9548442850308ecd8fc9a67681f4ea8403129e7867bcb85adaf6ec238 + languageName: node + linkType: hard + +"@babel/plugin-transform-unicode-property-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-property-regex@npm:7.24.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 276099b4483e707f80b054e2d29bc519158bfe52461ef5ff76f70727d592df17e30b1597ef4d8a0f04d810f6cb5a8dd887bdc1d0540af3744751710ef280090f + languageName: node + linkType: hard + +"@babel/plugin-transform-unicode-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-regex@npm:7.24.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0-0 + checksum: 400a0927bdb1425b4c0dc68a61b5b2d7d17c7d9f0e07317a1a6a373c080ef94be1dd65fdc4ac9a78fcdb58f89fd128450c7bc0d5b8ca0ae7eca3fbd98e50acba + languageName: node + linkType: hard + +"@babel/plugin-transform-unicode-sets-regex@npm:^7.24.1": + version: 7.24.1 + resolution: "@babel/plugin-transform-unicode-sets-regex@npm:7.24.1" + dependencies: + "@babel/helper-create-regexp-features-plugin": ^7.22.15 + "@babel/helper-plugin-utils": ^7.24.0 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 364342fb8e382dfaa23628b88e6484dc1097e53fb7199f4d338f1e2cd71d839bb0a35a9b1380074f6a10adb2e98b79d53ca3ec78c0b8c557ca895ffff42180df + languageName: node + linkType: hard + +"@babel/preset-env@npm:^7.16.4, @babel/preset-env@npm:^7.8.4, @babel/preset-env@npm:^7.9.5": + version: 7.24.4 + resolution: "@babel/preset-env@npm:7.24.4" + dependencies: + "@babel/compat-data": ^7.24.4 + "@babel/helper-compilation-targets": ^7.23.6 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": ^7.24.4 + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": ^7.24.1 + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": ^7.24.1 + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": ^7.24.1 + "@babel/plugin-proposal-private-property-in-object": 7.21.0-placeholder-for-preset-env.2 "@babel/plugin-syntax-async-generators": ^7.8.4 "@babel/plugin-syntax-class-properties": ^7.12.13 "@babel/plugin-syntax-class-static-block": ^7.14.5 "@babel/plugin-syntax-dynamic-import": ^7.8.3 "@babel/plugin-syntax-export-namespace-from": ^7.8.3 + "@babel/plugin-syntax-import-assertions": ^7.24.1 + "@babel/plugin-syntax-import-attributes": ^7.24.1 + "@babel/plugin-syntax-import-meta": ^7.10.4 "@babel/plugin-syntax-json-strings": ^7.8.3 "@babel/plugin-syntax-logical-assignment-operators": ^7.10.4 "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 @@ -1641,107 +1692,115 @@ __metadata: "@babel/plugin-syntax-optional-chaining": ^7.8.3 "@babel/plugin-syntax-private-property-in-object": ^7.14.5 "@babel/plugin-syntax-top-level-await": ^7.14.5 - "@babel/plugin-transform-arrow-functions": ^7.14.5 - "@babel/plugin-transform-async-to-generator": ^7.14.5 - "@babel/plugin-transform-block-scoped-functions": ^7.14.5 - "@babel/plugin-transform-block-scoping": ^7.14.5 - "@babel/plugin-transform-classes": ^7.14.5 - "@babel/plugin-transform-computed-properties": ^7.14.5 - "@babel/plugin-transform-destructuring": ^7.14.7 - "@babel/plugin-transform-dotall-regex": ^7.14.5 - "@babel/plugin-transform-duplicate-keys": ^7.14.5 - "@babel/plugin-transform-exponentiation-operator": ^7.14.5 - "@babel/plugin-transform-for-of": ^7.14.5 - "@babel/plugin-transform-function-name": ^7.14.5 - "@babel/plugin-transform-literals": ^7.14.5 - "@babel/plugin-transform-member-expression-literals": ^7.14.5 - "@babel/plugin-transform-modules-amd": ^7.14.5 - "@babel/plugin-transform-modules-commonjs": ^7.14.5 - "@babel/plugin-transform-modules-systemjs": ^7.14.5 - "@babel/plugin-transform-modules-umd": ^7.14.5 - "@babel/plugin-transform-named-capturing-groups-regex": ^7.14.7 - "@babel/plugin-transform-new-target": ^7.14.5 - "@babel/plugin-transform-object-super": ^7.14.5 - "@babel/plugin-transform-parameters": ^7.14.5 - "@babel/plugin-transform-property-literals": ^7.14.5 - "@babel/plugin-transform-regenerator": ^7.14.5 - "@babel/plugin-transform-reserved-words": ^7.14.5 - "@babel/plugin-transform-shorthand-properties": ^7.14.5 - "@babel/plugin-transform-spread": ^7.14.6 - "@babel/plugin-transform-sticky-regex": ^7.14.5 - "@babel/plugin-transform-template-literals": ^7.14.5 - "@babel/plugin-transform-typeof-symbol": ^7.14.5 - "@babel/plugin-transform-unicode-escapes": ^7.14.5 - "@babel/plugin-transform-unicode-regex": ^7.14.5 - "@babel/preset-modules": ^0.1.4 - "@babel/types": ^7.14.5 - babel-plugin-polyfill-corejs2: ^0.2.2 - babel-plugin-polyfill-corejs3: ^0.2.2 - babel-plugin-polyfill-regenerator: ^0.2.2 - core-js-compat: ^3.15.0 - semver: ^6.3.0 + "@babel/plugin-syntax-unicode-sets-regex": ^7.18.6 + "@babel/plugin-transform-arrow-functions": ^7.24.1 + "@babel/plugin-transform-async-generator-functions": ^7.24.3 + "@babel/plugin-transform-async-to-generator": ^7.24.1 + "@babel/plugin-transform-block-scoped-functions": ^7.24.1 + "@babel/plugin-transform-block-scoping": ^7.24.4 + "@babel/plugin-transform-class-properties": ^7.24.1 + "@babel/plugin-transform-class-static-block": ^7.24.4 + "@babel/plugin-transform-classes": ^7.24.1 + "@babel/plugin-transform-computed-properties": ^7.24.1 + "@babel/plugin-transform-destructuring": ^7.24.1 + "@babel/plugin-transform-dotall-regex": ^7.24.1 + "@babel/plugin-transform-duplicate-keys": ^7.24.1 + "@babel/plugin-transform-dynamic-import": ^7.24.1 + "@babel/plugin-transform-exponentiation-operator": ^7.24.1 + "@babel/plugin-transform-export-namespace-from": ^7.24.1 + "@babel/plugin-transform-for-of": ^7.24.1 + "@babel/plugin-transform-function-name": ^7.24.1 + "@babel/plugin-transform-json-strings": ^7.24.1 + "@babel/plugin-transform-literals": ^7.24.1 + "@babel/plugin-transform-logical-assignment-operators": ^7.24.1 + "@babel/plugin-transform-member-expression-literals": ^7.24.1 + "@babel/plugin-transform-modules-amd": ^7.24.1 + "@babel/plugin-transform-modules-commonjs": ^7.24.1 + "@babel/plugin-transform-modules-systemjs": ^7.24.1 + "@babel/plugin-transform-modules-umd": ^7.24.1 + "@babel/plugin-transform-named-capturing-groups-regex": ^7.22.5 + "@babel/plugin-transform-new-target": ^7.24.1 + "@babel/plugin-transform-nullish-coalescing-operator": ^7.24.1 + "@babel/plugin-transform-numeric-separator": ^7.24.1 + "@babel/plugin-transform-object-rest-spread": ^7.24.1 + "@babel/plugin-transform-object-super": ^7.24.1 + "@babel/plugin-transform-optional-catch-binding": ^7.24.1 + "@babel/plugin-transform-optional-chaining": ^7.24.1 + "@babel/plugin-transform-parameters": ^7.24.1 + "@babel/plugin-transform-private-methods": ^7.24.1 + "@babel/plugin-transform-private-property-in-object": ^7.24.1 + "@babel/plugin-transform-property-literals": ^7.24.1 + "@babel/plugin-transform-regenerator": ^7.24.1 + "@babel/plugin-transform-reserved-words": ^7.24.1 + "@babel/plugin-transform-shorthand-properties": ^7.24.1 + "@babel/plugin-transform-spread": ^7.24.1 + "@babel/plugin-transform-sticky-regex": ^7.24.1 + "@babel/plugin-transform-template-literals": ^7.24.1 + "@babel/plugin-transform-typeof-symbol": ^7.24.1 + "@babel/plugin-transform-unicode-escapes": ^7.24.1 + "@babel/plugin-transform-unicode-property-regex": ^7.24.1 + "@babel/plugin-transform-unicode-regex": ^7.24.1 + "@babel/plugin-transform-unicode-sets-regex": ^7.24.1 + "@babel/preset-modules": 0.1.6-no-external-plugins + babel-plugin-polyfill-corejs2: ^0.4.10 + babel-plugin-polyfill-corejs3: ^0.10.4 + babel-plugin-polyfill-regenerator: ^0.6.1 + core-js-compat: ^3.31.0 + semver: ^6.3.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: ebebc20ada68c92b67375926021d576af3636a279aee7625c1e234880355c8669188483aecfff2d478c1caa9fcf18b569ea329060b479236b04baed2bdf796d5 + checksum: 5a057a6463f92b02bfe66257d3f2c76878815bc7847f2a716b0539d9f547eae2a9d1f0fc62a5c0eff6ab0504bb52e815829ef893e4586b641f8dd6a609d114f3 languageName: node linkType: hard -"@babel/preset-modules@npm:^0.1.3, @babel/preset-modules@npm:^0.1.4": - version: 0.1.4 - resolution: "@babel/preset-modules@npm:0.1.4" +"@babel/preset-modules@npm:0.1.6-no-external-plugins": + version: 0.1.6-no-external-plugins + resolution: "@babel/preset-modules@npm:0.1.6-no-external-plugins" dependencies: "@babel/helper-plugin-utils": ^7.0.0 - "@babel/plugin-proposal-unicode-property-regex": ^7.4.4 - "@babel/plugin-transform-dotall-regex": ^7.4.4 "@babel/types": ^7.4.4 esutils: ^2.0.2 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 7c6500be06be9a341e377eb63292a4a22d0da2b4fb8c68714aff703ddb341cbd58e37d4119d64fc3e602f73801103af471fca2c60b4c1e48e08eea3e6b1afc93 + "@babel/core": ^7.0.0-0 || ^8.0.0-0 <8.0.0 + checksum: 4855e799bc50f2449fb5210f78ea9e8fd46cf4f242243f1e2ed838e2bd702e25e73e822e7f8447722a5f4baa5e67a8f7a0e403f3e7ce04540ff743a9c411c375 languageName: node linkType: hard -"@babel/preset-react@npm:7.9.1": - version: 7.9.1 - resolution: "@babel/preset-react@npm:7.9.1" +"@babel/preset-react@npm:^7.16.0, @babel/preset-react@npm:^7.9.4": + version: 7.24.1 + resolution: "@babel/preset-react@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-transform-react-display-name": ^7.8.3 - "@babel/plugin-transform-react-jsx": ^7.9.1 - "@babel/plugin-transform-react-jsx-development": ^7.9.0 - "@babel/plugin-transform-react-jsx-self": ^7.9.0 - "@babel/plugin-transform-react-jsx-source": ^7.9.0 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-transform-react-display-name": ^7.24.1 + "@babel/plugin-transform-react-jsx": ^7.23.4 + "@babel/plugin-transform-react-jsx-development": ^7.22.5 + "@babel/plugin-transform-react-pure-annotations": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 68efd5246694927d513a27bf4bb4b3894f489b5dc9eea883e7eda82341d152a3f3d6187fb2ed1b080064fa6a111ef53182ec43049ad766fb10af4440ef9bc62b + checksum: 70e146a6de480cb4b6c5eb197003960a2d148d513e1f5b5d04ee954f255d68c935c2800da13e550267f47b894bd0214b2548181467b52a4bdc0a85020061b68c languageName: node linkType: hard -"@babel/preset-react@npm:^7.0.0": - version: 7.14.5 - resolution: "@babel/preset-react@npm:7.14.5" +"@babel/preset-typescript@npm:^7.16.0": + version: 7.24.1 + resolution: "@babel/preset-typescript@npm:7.24.1" dependencies: - "@babel/helper-plugin-utils": ^7.14.5 - "@babel/helper-validator-option": ^7.14.5 - "@babel/plugin-transform-react-display-name": ^7.14.5 - "@babel/plugin-transform-react-jsx": ^7.14.5 - "@babel/plugin-transform-react-jsx-development": ^7.14.5 - "@babel/plugin-transform-react-pure-annotations": ^7.14.5 + "@babel/helper-plugin-utils": ^7.24.0 + "@babel/helper-validator-option": ^7.23.5 + "@babel/plugin-syntax-jsx": ^7.24.1 + "@babel/plugin-transform-modules-commonjs": ^7.24.1 + "@babel/plugin-transform-typescript": ^7.24.1 peerDependencies: "@babel/core": ^7.0.0-0 - checksum: 413c507f853b95c71ecb64f29ea7b0786464a237c54977b03a4410dd837b03bfa55df81d0e337f9792d9abc61f4bf3d616f857d00a36ff4ede79407c143ac865 + checksum: f3e0ff8c20dd5abc82614df2d7953f1549a98282b60809478f7dfb41c29be63720f2d1d7a51ef1f0d939b65e8666cb7d36e32bc4f8ac2b74c20664efd41e8bdd languageName: node linkType: hard -"@babel/preset-typescript@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/preset-typescript@npm:7.9.0" - dependencies: - "@babel/helper-plugin-utils": ^7.8.3 - "@babel/plugin-transform-typescript": ^7.9.0 - peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: fbdd8b3d0493df4c4a88a59ca616331658e219b4c294584834a34a5148c991b28173c8f244c3b4fcaee93cd1bad6c99c0a84bd0a47a4b3cc8e759f35a0d6a3eb +"@babel/regjsgen@npm:^0.8.0": + version: 0.8.0 + resolution: "@babel/regjsgen@npm:0.8.0" + checksum: 89c338fee774770e5a487382170711014d49a68eb281e74f2b5eac88f38300a4ad545516a7786a8dd5702e9cf009c94c2f582d200f077ac5decd74c56b973730 languageName: node linkType: hard @@ -1749,19 +1808,9 @@ __metadata: version: 7.24.4 resolution: "@babel/runtime-corejs2@npm:7.24.4" dependencies: - core-js: ^2.6.12 - regenerator-runtime: ^0.14.0 - checksum: f164006b7b63093ff407bc84988427bf56f01b1764a1eca2478139dcff131411e7c2ea10657e116ae47ccc0e96b165c8329a96336d2d421a05bb34d0292d3521 - languageName: node - linkType: hard - -"@babel/runtime-corejs3@npm:^7.12.1": - version: 7.14.7 - resolution: "@babel/runtime-corejs3@npm:7.14.7" - dependencies: - core-js-pure: ^3.15.0 - regenerator-runtime: ^0.13.4 - checksum: 9e49fc27e4de9fd5a97069aeeb0746cf0e42afe2068fa717a8abec740782a58d6bb1dc635c37a7bd47c40f3945fabad6308a44915520e15c7651f34b24b89d6f + core-js: ^2.6.12 + regenerator-runtime: ^0.14.0 + checksum: f164006b7b63093ff407bc84988427bf56f01b1764a1eca2478139dcff131411e7c2ea10657e116ae47ccc0e96b165c8329a96336d2d421a05bb34d0292d3521 languageName: node linkType: hard @@ -1774,16 +1823,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime@npm:7.9.0": - version: 7.9.0 - resolution: "@babel/runtime@npm:7.9.0" - dependencies: - regenerator-runtime: ^0.13.4 - checksum: dc9b50c1893460e71d93c299e659b61b41a37780e78c1e1404b360ca275d44b79107c0d986d74ac8163757f02384cda94d8315bded40deafe72ca07f7761a098 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.3.4, @babel/runtime@npm:^7.4.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.9.2": version: 7.14.6 resolution: "@babel/runtime@npm:7.14.6" dependencies: @@ -1792,18 +1832,16 @@ __metadata: languageName: node linkType: hard -"@babel/template@npm:^7.14.5, @babel/template@npm:^7.4.0, @babel/template@npm:^7.8.6": - version: 7.14.5 - resolution: "@babel/template@npm:7.14.5" +"@babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.16.3, @babel/runtime@npm:^7.23.2, @babel/runtime@npm:^7.5.5": + version: 7.24.4 + resolution: "@babel/runtime@npm:7.24.4" dependencies: - "@babel/code-frame": ^7.14.5 - "@babel/parser": ^7.14.5 - "@babel/types": ^7.14.5 - checksum: 4939199c5b1ca8940e14c87f30f4fab5f35c909bef88447131075349027546927b4e3e08e50db5c2db2024f2c6585a4fe571c739c835ac980f7a4ada2dd8a623 + regenerator-runtime: ^0.14.0 + checksum: 2f27d4c0ffac7ae7999ac0385e1106f2a06992a8bdcbf3da06adcac7413863cd08c198c2e4e970041bbea849e17f02e1df18875539b6afba76c781b6b59a07c3 languageName: node linkType: hard -"@babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0": +"@babel/template@npm:^7.10.4, @babel/template@npm:^7.22.15, @babel/template@npm:^7.24.0, @babel/template@npm:^7.3.3": version: 7.24.0 resolution: "@babel/template@npm:7.24.0" dependencies: @@ -1814,7 +1852,18 @@ __metadata: languageName: node linkType: hard -"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.13.0, @babel/traverse@npm:^7.14.5, @babel/traverse@npm:^7.24.1, @babel/traverse@npm:^7.4.3, @babel/traverse@npm:^7.7.0, @babel/traverse@npm:^7.9.0": +"@babel/template@npm:^7.14.5": + version: 7.14.5 + resolution: "@babel/template@npm:7.14.5" + dependencies: + "@babel/code-frame": ^7.14.5 + "@babel/parser": ^7.14.5 + "@babel/types": ^7.14.5 + checksum: 4939199c5b1ca8940e14c87f30f4fab5f35c909bef88447131075349027546927b4e3e08e50db5c2db2024f2c6585a4fe571c739c835ac980f7a4ada2dd8a623 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.1.0, @babel/traverse@npm:^7.12.1, @babel/traverse@npm:^7.14.5, @babel/traverse@npm:^7.24.1, @babel/traverse@npm:^7.7.0": version: 7.24.1 resolution: "@babel/traverse@npm:7.24.1" dependencies: @@ -1832,7 +1881,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.0.0, @babel/types@npm:^7.14.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.4.0, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0, @babel/types@npm:^7.9.0": +"@babel/types@npm:^7.0.0, @babel/types@npm:^7.14.5, @babel/types@npm:^7.3.0, @babel/types@npm:^7.4.4, @babel/types@npm:^7.7.0": version: 7.14.5 resolution: "@babel/types@npm:7.14.5" dependencies: @@ -1842,7 +1891,7 @@ __metadata: languageName: node linkType: hard -"@babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.24.0": +"@babel/types@npm:^7.12.1, @babel/types@npm:^7.12.6, @babel/types@npm:^7.20.7, @babel/types@npm:^7.22.15, @babel/types@npm:^7.22.19, @babel/types@npm:^7.22.5, @babel/types@npm:^7.23.0, @babel/types@npm:^7.23.4, @babel/types@npm:^7.24.0, @babel/types@npm:^7.3.3": version: 7.24.0 resolution: "@babel/types@npm:7.24.0" dependencies: @@ -1863,6 +1912,13 @@ __metadata: languageName: node linkType: hard +"@bcoe/v8-coverage@npm:^0.2.3": + version: 0.2.3 + resolution: "@bcoe/v8-coverage@npm:0.2.3" + checksum: 850f9305536d0f2bd13e9e0881cb5f02e4f93fad1189f7b2d4bebf694e3206924eadee1068130d43c11b750efcc9405f88a8e42ef098b6d75239c0f047de1a27 + languageName: node + linkType: hard + "@cnakazawa/watch@npm:^1.0.3": version: 1.0.4 resolution: "@cnakazawa/watch@npm:1.0.4" @@ -1995,6 +2051,23 @@ __metadata: languageName: node linkType: hard +"@eslint/eslintrc@npm:^0.4.3": + version: 0.4.3 + resolution: "@eslint/eslintrc@npm:0.4.3" + dependencies: + ajv: ^6.12.4 + debug: ^4.1.1 + espree: ^7.3.0 + globals: ^13.9.0 + ignore: ^4.0.6 + import-fresh: ^3.2.1 + js-yaml: ^3.13.1 + minimatch: ^3.0.4 + strip-json-comments: ^3.1.1 + checksum: 03a7704150b868c318aab6a94d87a33d30dc2ec579d27374575014f06237ba1370ae11178db772f985ef680d469dc237e7b16a1c5d8edaaeb8c3733e7a95a6d3 + languageName: node + linkType: hard + "@fortawesome/fontawesome-common-types@npm:^0.2.28": version: 0.2.35 resolution: "@fortawesome/fontawesome-common-types@npm:0.2.35" @@ -2083,7 +2156,7 @@ __metadata: languageName: node linkType: hard -"@hapi/joi@npm:^15.0.0": +"@hapi/joi@npm:^15.1.0": version: 15.1.1 resolution: "@hapi/joi@npm:15.1.1" dependencies: @@ -2133,175 +2206,227 @@ __metadata: languageName: node linkType: hard -"@jest/console@npm:^24.7.1, @jest/console@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/console@npm:24.9.0" +"@humanwhocodes/config-array@npm:^0.5.0": + version: 0.5.0 + resolution: "@humanwhocodes/config-array@npm:0.5.0" dependencies: - "@jest/source-map": ^24.9.0 - chalk: ^2.0.1 - slash: ^2.0.0 - checksum: ee6468c4aeeb8752126e92e20b0ffbf32abda731e9b7865b63b60bd569c3536e9c901efcec4d81c506a7c6fea2a970ace8262190961aba31dedbfeaa3459d78b + "@humanwhocodes/object-schema": ^1.2.0 + debug: ^4.1.1 + minimatch: ^3.0.4 + checksum: 44ee6a9f05d93dd9d5935a006b17572328ba9caff8002442f601736cbda79c580cc0f5a49ce9eb88fbacc5c3a6b62098357c2e95326cd17bb9f1a6c61d6e95e7 languageName: node linkType: hard -"@jest/core@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/core@npm:24.9.0" - dependencies: - "@jest/console": ^24.7.1 - "@jest/reporters": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/transform": ^24.9.0 - "@jest/types": ^24.9.0 - ansi-escapes: ^3.0.0 - chalk: ^2.0.1 +"@humanwhocodes/object-schema@npm:^1.2.0": + version: 1.2.1 + resolution: "@humanwhocodes/object-schema@npm:1.2.1" + checksum: a824a1ec31591231e4bad5787641f59e9633827d0a2eaae131a288d33c9ef0290bd16fda8da6f7c0fcb014147865d12118df10db57f27f41e20da92369fcb3f1 + languageName: node + linkType: hard + +"@istanbuljs/load-nyc-config@npm:^1.0.0": + version: 1.1.0 + resolution: "@istanbuljs/load-nyc-config@npm:1.1.0" + dependencies: + camelcase: ^5.3.1 + find-up: ^4.1.0 + get-package-type: ^0.1.0 + js-yaml: ^3.13.1 + resolve-from: ^5.0.0 + checksum: d578da5e2e804d5c93228450a1380e1a3c691de4953acc162f387b717258512a3e07b83510a936d9fab03eac90817473917e24f5d16297af3867f59328d58568 + languageName: node + linkType: hard + +"@istanbuljs/schema@npm:^0.1.2": + version: 0.1.3 + resolution: "@istanbuljs/schema@npm:0.1.3" + checksum: 5282759d961d61350f33d9118d16bcaed914ebf8061a52f4fa474b2cb08720c9c81d165e13b82f2e5a8a212cc5af482f0c6fc1ac27b9e067e5394c9a6ed186c9 + languageName: node + linkType: hard + +"@jest/console@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/console@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + "@types/node": "*" + chalk: ^4.0.0 + jest-message-util: ^26.6.2 + jest-util: ^26.6.2 + slash: ^3.0.0 + checksum: 69a9ca6ba357d7634fd537e3b87c64369865ffb59f57fe6661223088bd62273d0c1d660fefce3625a427f42a37d32590f6b291e1295ea6d6b7cb31ddae36a737 + languageName: node + linkType: hard + +"@jest/core@npm:^26.6.0, @jest/core@npm:^26.6.3": + version: 26.6.3 + resolution: "@jest/core@npm:26.6.3" + dependencies: + "@jest/console": ^26.6.2 + "@jest/reporters": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 exit: ^0.1.2 - graceful-fs: ^4.1.15 - jest-changed-files: ^24.9.0 - jest-config: ^24.9.0 - jest-haste-map: ^24.9.0 - jest-message-util: ^24.9.0 - jest-regex-util: ^24.3.0 - jest-resolve: ^24.9.0 - jest-resolve-dependencies: ^24.9.0 - jest-runner: ^24.9.0 - jest-runtime: ^24.9.0 - jest-snapshot: ^24.9.0 - jest-util: ^24.9.0 - jest-validate: ^24.9.0 - jest-watcher: ^24.9.0 - micromatch: ^3.1.10 - p-each-series: ^1.0.0 - realpath-native: ^1.1.0 - rimraf: ^2.5.4 - slash: ^2.0.0 - strip-ansi: ^5.0.0 - checksum: 44d63883bc410ea2448eb359c417b92d9dd5fb9bec51f28bde2bd87ade705c4f0f6698f0c251a679204e860bf865120c58725cf397465862c99a70327bcb99fc + graceful-fs: ^4.2.4 + jest-changed-files: ^26.6.2 + jest-config: ^26.6.3 + jest-haste-map: ^26.6.2 + jest-message-util: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-resolve-dependencies: ^26.6.3 + jest-runner: ^26.6.3 + jest-runtime: ^26.6.3 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 + jest-watcher: ^26.6.2 + micromatch: ^4.0.2 + p-each-series: ^2.1.0 + rimraf: ^3.0.0 + slash: ^3.0.0 + strip-ansi: ^6.0.0 + checksum: f52b26ffe9b923ed67b3ff30e170b3a434d4263990f78d96cd43acbd0aa8ad36aecad2f1822f376da3a80228714fd6b7f7acd51744133cfcd2780ba0e3da537b languageName: node linkType: hard -"@jest/environment@npm:^24.3.0, @jest/environment@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/environment@npm:24.9.0" +"@jest/environment@npm:^26.6.0, @jest/environment@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/environment@npm:26.6.2" dependencies: - "@jest/fake-timers": ^24.9.0 - "@jest/transform": ^24.9.0 - "@jest/types": ^24.9.0 - jest-mock: ^24.9.0 - checksum: 6a663c05713ad0cd1dc7c5bf715a3e5e655e73ee02497ab0a9dea4fe0855226504535c504d265c054c8b4bafb1216dff0e7e0e3b4ed064bda4c3d6efe74fe369 + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + jest-mock: ^26.6.2 + checksum: 7748081b2a758161785aff161780b05084dccaff908c8ed82c04f7da5d5e5439e77b5eb667306d5c4e1422653c7a67ed2955f26704f48c65c404195e1e21780a languageName: node linkType: hard -"@jest/fake-timers@npm:^24.3.0, @jest/fake-timers@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/fake-timers@npm:24.9.0" +"@jest/fake-timers@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/fake-timers@npm:26.6.2" dependencies: - "@jest/types": ^24.9.0 - jest-message-util: ^24.9.0 - jest-mock: ^24.9.0 - checksum: d49ab33e28b070d5be75659ed89d4b79e74012c8c28ecf51cf9b89732ba5b2a57129787dd144949c048a0460ed62f1e32079a4b10d896c75bde024699d7a2c5c + "@jest/types": ^26.6.2 + "@sinonjs/fake-timers": ^6.0.1 + "@types/node": "*" + jest-message-util: ^26.6.2 + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + checksum: c732658fac4014a424e6629495296c3b2e8697787518df34c74539ec139625e7141ad792b8a4d3c8392b47954ad01be9846b7c57cc8c631490969e7cafa84e6a languageName: node linkType: hard -"@jest/reporters@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/reporters@npm:24.9.0" +"@jest/globals@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/globals@npm:26.6.2" + dependencies: + "@jest/environment": ^26.6.2 + "@jest/types": ^26.6.2 + expect: ^26.6.2 + checksum: 49b28d0cc7e99898eeaf23e6899e3c9ee25a2a4831caa3eb930ec1722de2e92a0e8a6a6f649438fdd20ff0c0d5e522dd78cb719466a57f011a88d60419b903c5 + languageName: node + linkType: hard + +"@jest/reporters@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/reporters@npm:26.6.2" dependencies: - "@jest/environment": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/transform": ^24.9.0 - "@jest/types": ^24.9.0 - chalk: ^2.0.1 + "@bcoe/v8-coverage": ^0.2.3 + "@jest/console": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + chalk: ^4.0.0 + collect-v8-coverage: ^1.0.0 exit: ^0.1.2 glob: ^7.1.2 - istanbul-lib-coverage: ^2.0.2 - istanbul-lib-instrument: ^3.0.1 - istanbul-lib-report: ^2.0.4 - istanbul-lib-source-maps: ^3.0.1 - istanbul-reports: ^2.2.6 - jest-haste-map: ^24.9.0 - jest-resolve: ^24.9.0 - jest-runtime: ^24.9.0 - jest-util: ^24.9.0 - jest-worker: ^24.6.0 - node-notifier: ^5.4.2 - slash: ^2.0.0 + graceful-fs: ^4.2.4 + istanbul-lib-coverage: ^3.0.0 + istanbul-lib-instrument: ^4.0.3 + istanbul-lib-report: ^3.0.0 + istanbul-lib-source-maps: ^4.0.0 + istanbul-reports: ^3.0.2 + jest-haste-map: ^26.6.2 + jest-resolve: ^26.6.2 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 + node-notifier: ^8.0.0 + slash: ^3.0.0 source-map: ^0.6.0 - string-length: ^2.0.0 - checksum: 588539d0d9a5e483e5e09c1dd7c42b6490199cb0588a9ae8eb1b2c34a74cf7da0bba5dd425c19307a9d95a075bfc4feb0221d3847b9542a3a727342e3f30e5a1 + string-length: ^4.0.1 + terminal-link: ^2.0.0 + v8-to-istanbul: ^7.0.0 + dependenciesMeta: + node-notifier: + optional: true + checksum: 53c7a697c562becb7682a9a6248ea553013bf7048c08ddce5bf9fb53b975fc9f799ca163f7494e0be6c4d3cf181c8bc392976268da52b7de8ce4470b971ed84e languageName: node linkType: hard -"@jest/source-map@npm:^24.3.0, @jest/source-map@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/source-map@npm:24.9.0" +"@jest/source-map@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/source-map@npm:26.6.2" dependencies: callsites: ^3.0.0 - graceful-fs: ^4.1.15 + graceful-fs: ^4.2.4 source-map: ^0.6.0 - checksum: 00479faf6854d5d183b94465db1a0876980ced72bf26cb6a2fe8c04977dc2692e6529faa6b64269492d1d9cab51feebaac9d453d1e6bb1306fc15777143b72af + checksum: b171cef442738887dda85527ab78229996db5946c6435ddb56d442c2851889ba493729a9de73100f1a31b9a31a91207b55bc75656ae7df9843d65078b925385e languageName: node linkType: hard -"@jest/test-result@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/test-result@npm:24.9.0" +"@jest/test-result@npm:^26.6.0, @jest/test-result@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/test-result@npm:26.6.2" dependencies: - "@jest/console": ^24.9.0 - "@jest/types": ^24.9.0 + "@jest/console": ^26.6.2 + "@jest/types": ^26.6.2 "@types/istanbul-lib-coverage": ^2.0.0 - checksum: 7145c7baa289798881160b3cfa5b2466b2636238a52b77cf46e5468ffe2881fb8fb8d4966155a8d508b26a8d29a302a9eb9037de1a371e5dc9bb6e94837c0ae7 + collect-v8-coverage: ^1.0.0 + checksum: dcb6175825231e9377e43546aed4edd6acc22f1788d5f099bbba36bb55b9115a92f760e88426c076bcdeff5a50d8f697327a920db0cd1fb339781fc3713fa8c7 languageName: node linkType: hard -"@jest/test-sequencer@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/test-sequencer@npm:24.9.0" +"@jest/test-sequencer@npm:^26.6.3": + version: 26.6.3 + resolution: "@jest/test-sequencer@npm:26.6.3" dependencies: - "@jest/test-result": ^24.9.0 - jest-haste-map: ^24.9.0 - jest-runner: ^24.9.0 - jest-runtime: ^24.9.0 - checksum: 049bea54743925b361bf10acce8a1de8e9a2ac9b5158044d484f3fc5748f975d52d8260e9ff2621fc29b5b586a17e54693670c7dfa75b09f5e83e87f2a63aac2 + "@jest/test-result": ^26.6.2 + graceful-fs: ^4.2.4 + jest-haste-map: ^26.6.2 + jest-runner: ^26.6.3 + jest-runtime: ^26.6.3 + checksum: a3450b3d7057f74da1828bb7b3658f228a7c049dc4082c5c49b8bafbd8f69d102a8a99007b7ed5d43464712f7823f53fe3564fda17787f178c219cccf329a461 languageName: node linkType: hard -"@jest/transform@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/transform@npm:24.9.0" +"@jest/transform@npm:^26.6.2": + version: 26.6.2 + resolution: "@jest/transform@npm:26.6.2" dependencies: "@babel/core": ^7.1.0 - "@jest/types": ^24.9.0 - babel-plugin-istanbul: ^5.1.0 - chalk: ^2.0.1 + "@jest/types": ^26.6.2 + babel-plugin-istanbul: ^6.0.0 + chalk: ^4.0.0 convert-source-map: ^1.4.0 fast-json-stable-stringify: ^2.0.0 - graceful-fs: ^4.1.15 - jest-haste-map: ^24.9.0 - jest-regex-util: ^24.9.0 - jest-util: ^24.9.0 - micromatch: ^3.1.10 + graceful-fs: ^4.2.4 + jest-haste-map: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-util: ^26.6.2 + micromatch: ^4.0.2 pirates: ^4.0.1 - realpath-native: ^1.1.0 - slash: ^2.0.0 + slash: ^3.0.0 source-map: ^0.6.1 - write-file-atomic: 2.4.1 - checksum: 0153bcd6a9b464c85ee8b67c360f745ab8e41b1b363220f1f12ed644a667dceb6666366017f7f849a8f6cde960020b638b8557eae852af0537520b0903881fbd - languageName: node - linkType: hard - -"@jest/types@npm:^24.3.0, @jest/types@npm:^24.9.0": - version: 24.9.0 - resolution: "@jest/types@npm:24.9.0" - dependencies: - "@types/istanbul-lib-coverage": ^2.0.0 - "@types/istanbul-reports": ^1.1.1 - "@types/yargs": ^13.0.0 - checksum: 603698f774cf22f9d16a0e0fac9e10e7db21052aebfa33db154c8a5940e0eb1fa9c079a8c91681041ad3aeee2adfa950608dd0c663130316ba034b8bca7b301c + write-file-atomic: ^3.0.0 + checksum: 31667b925a2f3b310d854495da0ab67be8f5da24df76ecfc51162e75f1140aed5d18069ba190cb5e0c7e492b04272c8c79076ddf5bbcff530ee80a16a02c4545 languageName: node linkType: hard -"@jest/types@npm:^26.6.2": +"@jest/types@npm:^26.6.0, @jest/types@npm:^26.6.2": version: 26.6.2 resolution: "@jest/types@npm:26.6.2" dependencies: @@ -2339,6 +2464,16 @@ __metadata: languageName: node linkType: hard +"@jridgewell/source-map@npm:^0.3.3": + version: 0.3.6 + resolution: "@jridgewell/source-map@npm:0.3.6" + dependencies: + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + checksum: c9dc7d899397df95e3c9ec287b93c0b56f8e4453cd20743e2b9c8e779b1949bc3cccf6c01bb302779e46560eb45f62ea38d19fedd25370d814734268450a9f30 + languageName: node + linkType: hard + "@jridgewell/sourcemap-codec@npm:^1.4.10, @jridgewell/sourcemap-codec@npm:^1.4.14": version: 1.4.15 resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" @@ -2437,16 +2572,6 @@ __metadata: languageName: node linkType: hard -"@mrmlnc/readdir-enhanced@npm:^2.2.1": - version: 2.2.1 - resolution: "@mrmlnc/readdir-enhanced@npm:2.2.1" - dependencies: - call-me-maybe: ^1.0.1 - glob-to-regexp: ^0.3.0 - checksum: d3b82b29368821154ce8e10bef5ccdbfd070d3e9601643c99ea4607e56f3daeaa4e755dd6d2355da20762c695c1b0570543d9f84b48f70c211ec09c4aaada2e1 - languageName: node - linkType: hard - "@nodelib/fs.scandir@npm:2.1.5": version: 2.1.5 resolution: "@nodelib/fs.scandir@npm:2.1.5" @@ -2464,20 +2589,13 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.stat@npm:^1.1.2": - version: 1.1.3 - resolution: "@nodelib/fs.stat@npm:1.1.3" - checksum: 318deab369b518a34778cdaa0054dd28a4381c0c78e40bbd20252f67d084b1d7bf9295fea4423de2c19ac8e1a34f120add9125f481b2a710f7068bcac7e3e305 - languageName: node - linkType: hard - "@nodelib/fs.walk@npm:^1.2.3": - version: 1.2.7 - resolution: "@nodelib/fs.walk@npm:1.2.7" + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: "@nodelib/fs.scandir": 2.1.5 fastq: ^1.6.0 - checksum: f5286c39c2f9cc0e89b2cbee6b735c5cf572c37f9c0a47a16ce3c1d9ba5d488f3153976ceb1b984ad09dbd8d1de620fab3e7b0ef2b64a006267d0895a16ce95c + checksum: 190c643f156d8f8f277bf2a6078af1ffde1fd43f498f187c2db24d35b4b4b5785c02c7dc52e356497b9a1b65b13edc996de08de0b961c32844364da02986dc53 languageName: node linkType: hard @@ -2532,6 +2650,42 @@ __metadata: languageName: node linkType: hard +"@pmmmwh/react-refresh-webpack-plugin@npm:0.4.2": + version: 0.4.2 + resolution: "@pmmmwh/react-refresh-webpack-plugin@npm:0.4.2" + dependencies: + ansi-html: ^0.0.7 + error-stack-parser: ^2.0.6 + html-entities: ^1.2.1 + native-url: ^0.2.6 + schema-utils: ^2.6.5 + source-map: ^0.7.3 + peerDependencies: + "@types/webpack": 4.x + react-refresh: ^0.8.3 + sockjs-client: ^1.4.0 + type-fest: ^0.13.1 + webpack: ">=4.43.0 <6.0.0" + webpack-dev-server: 3.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 0.x || 1.x + peerDependenciesMeta: + "@types/webpack": + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + checksum: b7f70926f64c996fb9a9dd0993a2b90f516fd01e5dab2841ff4f2a66cabf901cdb08c14698e3e1daf02cbcdd3170ab1736a6ad65fe7c1ffcfab2543b290a201d + languageName: node + linkType: hard + "@popperjs/core@npm:^2.9.0": version: 2.11.6 resolution: "@popperjs/core@npm:2.11.6" @@ -2539,6 +2693,46 @@ __metadata: languageName: node linkType: hard +"@rollup/plugin-node-resolve@npm:^7.1.1": + version: 7.1.3 + resolution: "@rollup/plugin-node-resolve@npm:7.1.3" + dependencies: + "@rollup/pluginutils": ^3.0.8 + "@types/resolve": 0.0.8 + builtin-modules: ^3.1.0 + is-module: ^1.0.0 + resolve: ^1.14.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: e787c35f123652762d212b63f8cfaf577307434a935466397021c31b71d0d94357c6fa4e326b49bf44b959e22e41bc21f5648470eabec086566e7c36c5d041b1 + languageName: node + linkType: hard + +"@rollup/plugin-replace@npm:^2.3.1": + version: 2.4.2 + resolution: "@rollup/plugin-replace@npm:2.4.2" + dependencies: + "@rollup/pluginutils": ^3.1.0 + magic-string: ^0.25.7 + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + checksum: b2f1618ee5526d288e2f8ae328dcb326e20e8dc8bd1f60d3e14d6708a5832e4aa44811f7d493f4aed2deeadca86e3b6b0503cd39bf50cfb4b595bb9da027fad0 + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^3.0.8, @rollup/pluginutils@npm:^3.1.0": + version: 3.1.0 + resolution: "@rollup/pluginutils@npm:3.1.0" + dependencies: + "@types/estree": 0.0.39 + estree-walker: ^1.0.1 + picomatch: ^2.2.2 + peerDependencies: + rollup: ^1.20.0||^2.0.0 + checksum: 8be16e27863c219edbb25a4e6ec2fe0e1e451d9e917b6a43cf2ae5bc025a6b8faaa40f82a6e53b66d0de37b58ff472c6c3d57a83037ae635041f8df959d6d9aa + languageName: node + linkType: hard + "@sinonjs/commons@npm:^1, @sinonjs/commons@npm:^1.3.0, @sinonjs/commons@npm:^1.4.0, @sinonjs/commons@npm:^1.7.0": version: 1.8.3 resolution: "@sinonjs/commons@npm:1.8.3" @@ -2566,6 +2760,15 @@ __metadata: languageName: node linkType: hard +"@sinonjs/fake-timers@npm:^6.0.1": + version: 6.0.1 + resolution: "@sinonjs/fake-timers@npm:6.0.1" + dependencies: + "@sinonjs/commons": ^1.7.0 + checksum: 8e331aa1412d905ecc8efd63550f58a6f77dcb510f878172004e53be63eb82650623618763001a918fc5e21257b86c45041e4e97c454ed6a2d187de084abbd11 + languageName: node + linkType: hard + "@sinonjs/formatio@npm:^3.2.1": version: 3.2.2 resolution: "@sinonjs/formatio@npm:3.2.2" @@ -2594,134 +2797,144 @@ __metadata: languageName: node linkType: hard -"@svgr/babel-plugin-add-jsx-attribute@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:4.2.0" - checksum: 3e67319517c4dbed247ca1c28050028fd8990d0745d28424c70db0999143b8e19f2dba563546e1acb842e89d4732149257462b432d6e8935712eba935c5928c3 +"@surma/rollup-plugin-off-main-thread@npm:^1.1.1": + version: 1.4.2 + resolution: "@surma/rollup-plugin-off-main-thread@npm:1.4.2" + dependencies: + ejs: ^2.6.1 + magic-string: ^0.25.0 + checksum: da721792036a0e1253911f9b5280e6cb236024d7d2255bde3b6e87587c0ea8f46404224c8c032a27ee11ab3244eda752587fb37ec78c2e64eb53e10557373102 languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-attribute@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:4.2.0" - checksum: cc831c7b77a333548771190bcb50ad5f121c4cd5f397a7628b6c14df93a69e89a1d4a0b36b0bceda91f46c6fed3074406851252368aa6772248b1023f1b903f0 +"@svgr/babel-plugin-add-jsx-attribute@npm:^5.4.0": + version: 5.4.0 + resolution: "@svgr/babel-plugin-add-jsx-attribute@npm:5.4.0" + checksum: 1c538cf312b486598c6aea17f9b72d7fc308eb5dd32effd804630206a185493b8a828ff980ceb29d57d8319c085614c7cea967be709c71ae77702a4c30037011 languageName: node linkType: hard -"@svgr/babel-plugin-remove-jsx-empty-expression@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:4.2.0" - checksum: dedd4c4b9947b44daa02ab7846f8931463f70eca62bc58a16ffec2dd3538ec12e4e654ce7f4fcea79f88f176bba4548352035a5da0e7bc56c6197d44e0e0bd9c +"@svgr/babel-plugin-remove-jsx-attribute@npm:^5.4.0": + version: 5.4.0 + resolution: "@svgr/babel-plugin-remove-jsx-attribute@npm:5.4.0" + checksum: ad2231bfcb14daa944201df66236c222cde05a07c4cffaecab1d36d33f606b6caf17bda21844fc435780c1a27195e49beb8397536fe5e7545dfffcfbbcecb7f8 languageName: node linkType: hard -"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:4.2.0" - checksum: 5c0af9239454ddfa5cadceff6a5292e04601ddb60ccaa78197ff825b9577d868b277d22225be31118926249e79f12f5dc44c03e284838325230e421c98d497ed +"@svgr/babel-plugin-remove-jsx-empty-expression@npm:^5.0.1": + version: 5.0.1 + resolution: "@svgr/babel-plugin-remove-jsx-empty-expression@npm:5.0.1" + checksum: 175c8f13ddcb0744f7c3910ebed3799cfb961a75bff130e1ed2071c87ca8b8df8964825c988e511b2e3c5dbf48ad3d4fbbb6989edc53294253df40cf2a24375e languageName: node linkType: hard -"@svgr/babel-plugin-svg-dynamic-title@npm:^4.3.3": - version: 4.3.3 - resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:4.3.3" - checksum: 401964bb8aa4bcc9fab5f3eca4b73099f6c8a984b791a1b97a5544d6da1108f92ddc32275de8e5a12e330f129532ded6a804efcda20338b2062ce3087309f317 +"@svgr/babel-plugin-replace-jsx-attribute-value@npm:^5.0.1": + version: 5.0.1 + resolution: "@svgr/babel-plugin-replace-jsx-attribute-value@npm:5.0.1" + checksum: 68f4e2a5b95eca44e22fce485dc2ddd10adabe2b38f6db3ef9071b35e84bf379685f7acab6c05b7a82f722328c02f6424f8252c6dd5c2c4ed2f00104072b1dfe languageName: node linkType: hard -"@svgr/babel-plugin-svg-em-dimensions@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:4.2.0" - checksum: f3a86e2e29d1bc67a42bf80240680be5ca59219bc63193e517619385c9888a13eb369cc97bdecbed16b392db7f3faa56cf397f1be215e2ce27316249f9deff97 +"@svgr/babel-plugin-svg-dynamic-title@npm:^5.4.0": + version: 5.4.0 + resolution: "@svgr/babel-plugin-svg-dynamic-title@npm:5.4.0" + checksum: c46feb52454acea32031d1d881a81334f2e5f838ed25a2d9014acb5e9541d404405911e86dbee8bee9f1e43c9e07118123a07dc297962dbed0c4c5a86bdc4be9 languageName: node linkType: hard -"@svgr/babel-plugin-transform-react-native-svg@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:4.2.0" - checksum: b847d9356fd67844bdb0bf1492f84e3a2adc17ee3e89d3fb26734382155d5b192a5575114d3aafb5bc2e364e4e536ce56c25c92aba1c4c08cef7a5441922cfa4 +"@svgr/babel-plugin-svg-em-dimensions@npm:^5.4.0": + version: 5.4.0 + resolution: "@svgr/babel-plugin-svg-em-dimensions@npm:5.4.0" + checksum: 0d19b26147bbba932bd973258dab4a80a7ea6b9d674713186f0e10fa21a9e3aa4327326b2bf1892e8051712bce0ea30561eb187ca27bb241d33c350cea51ac88 languageName: node linkType: hard -"@svgr/babel-plugin-transform-svg-component@npm:^4.2.0": - version: 4.2.0 - resolution: "@svgr/babel-plugin-transform-svg-component@npm:4.2.0" - checksum: 17084831fb03b78d868155f24e47c6d9a92215a7519d17604cdd000f4a2f873ad16c499a7b421c7e2577e7e5ac3dfe02eb693965881a65fe141ad57600e117e1 +"@svgr/babel-plugin-transform-react-native-svg@npm:^5.4.0": + version: 5.4.0 + resolution: "@svgr/babel-plugin-transform-react-native-svg@npm:5.4.0" + checksum: 8ac5dc9fb2dee24addc74dbcb169860c95a69247606f986eabb0618fb300dd08e8f220891b758e62c051428ba04d8dd50f2c2bf877e15fa190e6d384d1ccd2ad languageName: node linkType: hard -"@svgr/babel-preset@npm:^4.3.3": - version: 4.3.3 - resolution: "@svgr/babel-preset@npm:4.3.3" +"@svgr/babel-plugin-transform-svg-component@npm:^5.5.0": + version: 5.5.0 + resolution: "@svgr/babel-plugin-transform-svg-component@npm:5.5.0" + checksum: 94c3fed490deb8544af4ea32a5d78a840334cdcc8a5a33fe8ea9f1c220a4d714d57c9e10934492de99b7e1acc17963b1749a49927e27b1e839a4dc3c893605c7 + languageName: node + linkType: hard + +"@svgr/babel-preset@npm:^5.5.0": + version: 5.5.0 + resolution: "@svgr/babel-preset@npm:5.5.0" dependencies: - "@svgr/babel-plugin-add-jsx-attribute": ^4.2.0 - "@svgr/babel-plugin-remove-jsx-attribute": ^4.2.0 - "@svgr/babel-plugin-remove-jsx-empty-expression": ^4.2.0 - "@svgr/babel-plugin-replace-jsx-attribute-value": ^4.2.0 - "@svgr/babel-plugin-svg-dynamic-title": ^4.3.3 - "@svgr/babel-plugin-svg-em-dimensions": ^4.2.0 - "@svgr/babel-plugin-transform-react-native-svg": ^4.2.0 - "@svgr/babel-plugin-transform-svg-component": ^4.2.0 - checksum: a1ccdd34ac96ecb73f8ebb02a111602935b59cfa824fa9b9c20c38bc88bb9f176caab602f81c1dc3b00b0d56795ebc3d10153e97466291345cfc8eaf92e13d5f + "@svgr/babel-plugin-add-jsx-attribute": ^5.4.0 + "@svgr/babel-plugin-remove-jsx-attribute": ^5.4.0 + "@svgr/babel-plugin-remove-jsx-empty-expression": ^5.0.1 + "@svgr/babel-plugin-replace-jsx-attribute-value": ^5.0.1 + "@svgr/babel-plugin-svg-dynamic-title": ^5.4.0 + "@svgr/babel-plugin-svg-em-dimensions": ^5.4.0 + "@svgr/babel-plugin-transform-react-native-svg": ^5.4.0 + "@svgr/babel-plugin-transform-svg-component": ^5.5.0 + checksum: 5d396c4499c9ff2df9db6d08a160d10386b9f459cb9c2bb5ee183ab03b2f46c8ef3c9a070f1eee93f4e4433a5f00704e7632b1386078eb697ad8a2b38edb8522 languageName: node linkType: hard -"@svgr/core@npm:^4.3.3": - version: 4.3.3 - resolution: "@svgr/core@npm:4.3.3" +"@svgr/core@npm:^5.4.0": + version: 5.5.0 + resolution: "@svgr/core@npm:5.5.0" dependencies: - "@svgr/plugin-jsx": ^4.3.3 - camelcase: ^5.3.1 - cosmiconfig: ^5.2.1 - checksum: 014c7dae4e1523ffdb6662a7396975476b802614d5477780b71e292c2fe789faa3e0572ce845b3dbd45098b0e3affdfc63dea742e316c5d1bac2d2c77afd8838 + "@svgr/plugin-jsx": ^5.5.0 + camelcase: ^6.2.0 + cosmiconfig: ^7.0.0 + checksum: 39b230151e30b9ca8551d10674e50efb821d1a49ce10969b09587af130780eba581baa1e321b0922f48331943096f05590aa6ae92d88d011d58093a89dd34158 languageName: node linkType: hard -"@svgr/hast-util-to-babel-ast@npm:^4.3.2": - version: 4.3.2 - resolution: "@svgr/hast-util-to-babel-ast@npm:4.3.2" +"@svgr/hast-util-to-babel-ast@npm:^5.5.0": + version: 5.5.0 + resolution: "@svgr/hast-util-to-babel-ast@npm:5.5.0" dependencies: - "@babel/types": ^7.4.4 - checksum: 0d68084731afd1818ddbaecfc9201a24e10370f88c894eaaf48da9c4db93cd4bf5b7a8e03d1fcd4446165718e5ee124450ecab9f9a22208f87b2fa223ea6d3ca + "@babel/types": ^7.12.6 + checksum: a03c1c7ab92b1a6dbd7671b0b78df4c07e8d808ff092671554a78752ec0c0425c03b6c82569a5f33903d191c73379eedf631f23aeb30b7a70185f5f2fc67fae6 languageName: node linkType: hard -"@svgr/plugin-jsx@npm:^4.3.3": - version: 4.3.3 - resolution: "@svgr/plugin-jsx@npm:4.3.3" +"@svgr/plugin-jsx@npm:^5.4.0, @svgr/plugin-jsx@npm:^5.5.0": + version: 5.5.0 + resolution: "@svgr/plugin-jsx@npm:5.5.0" dependencies: - "@babel/core": ^7.4.5 - "@svgr/babel-preset": ^4.3.3 - "@svgr/hast-util-to-babel-ast": ^4.3.2 - svg-parser: ^2.0.0 - checksum: 880ae8c6b841c84a71ef3b1b6954089925f4b5f4a1f31767b2ce9004d7f72bfff7d66af05099a3e48612f10b242206d97a0991d366f3648c3e8df5c63cf665f5 + "@babel/core": ^7.12.3 + "@svgr/babel-preset": ^5.5.0 + "@svgr/hast-util-to-babel-ast": ^5.5.0 + svg-parser: ^2.0.2 + checksum: e053f8dd6bfcd72377b432dd5b1db3c89d503d29839639a87f85b597a680d0b69e33a4db376f5a1074a89615f7157cd36f63f94bdb4083a0fd5bbe918c7fcb9b languageName: node linkType: hard -"@svgr/plugin-svgo@npm:^4.3.1": - version: 4.3.1 - resolution: "@svgr/plugin-svgo@npm:4.3.1" +"@svgr/plugin-svgo@npm:^5.4.0": + version: 5.5.0 + resolution: "@svgr/plugin-svgo@npm:5.5.0" dependencies: - cosmiconfig: ^5.2.1 - merge-deep: ^3.0.2 + cosmiconfig: ^7.0.0 + deepmerge: ^4.2.2 svgo: ^1.2.2 - checksum: 8d68f29d9c7d9c00fc079de25b58e0f83365cddc0e079e792ec9d76c7a676269029d22466aa9ab8493f0794130711fb6f20e9779cfa197f84da20285c37f2a3c + checksum: bef5d09581349afdf654209f82199670649cc749b81ff5f310ce4a3bbad749cde877c9b1a711dd9ced51224e2b5b5a720d242bdf183fa0f83e08e8d5e069b0b6 languageName: node linkType: hard -"@svgr/webpack@npm:4.3.3": - version: 4.3.3 - resolution: "@svgr/webpack@npm:4.3.3" - dependencies: - "@babel/core": ^7.4.5 - "@babel/plugin-transform-react-constant-elements": ^7.0.0 - "@babel/preset-env": ^7.4.5 - "@babel/preset-react": ^7.0.0 - "@svgr/core": ^4.3.3 - "@svgr/plugin-jsx": ^4.3.3 - "@svgr/plugin-svgo": ^4.3.1 - loader-utils: ^1.2.3 - checksum: e5ec59ee492c73c26cd22220ac1038fb61681cb22048485aa68edf850328be6effe93900fbb60dab735fad7e6939a598c5c9fe46768c1cb74c1b3a3330555e43 +"@svgr/webpack@npm:5.4.0": + version: 5.4.0 + resolution: "@svgr/webpack@npm:5.4.0" + dependencies: + "@babel/core": ^7.9.0 + "@babel/plugin-transform-react-constant-elements": ^7.9.0 + "@babel/preset-env": ^7.9.5 + "@babel/preset-react": ^7.9.4 + "@svgr/core": ^5.4.0 + "@svgr/plugin-jsx": ^5.4.0 + "@svgr/plugin-svgo": ^5.4.0 + loader-utils: ^2.0.0 + checksum: f814b0eb4106ce7e9f0df3ed07969f11d435e82a331d76a1bfde6de7614b78591d2e9dce4683e5c7a121d427c2ce9bade542d2256aee33a62aa14581e243f556 languageName: node linkType: hard @@ -2739,16 +2952,16 @@ __metadata: languageName: node linkType: hard -"@types/babel__core@npm:^7.1.0": - version: 7.1.14 - resolution: "@types/babel__core@npm:7.1.14" +"@types/babel__core@npm:^7.0.0, @types/babel__core@npm:^7.1.7": + version: 7.20.5 + resolution: "@types/babel__core@npm:7.20.5" dependencies: - "@babel/parser": ^7.1.0 - "@babel/types": ^7.0.0 + "@babel/parser": ^7.20.7 + "@babel/types": ^7.20.7 "@types/babel__generator": "*" "@types/babel__template": "*" "@types/babel__traverse": "*" - checksum: de4a1a4905e4fb66e9b5ea185704b209892fa104b6aec8705021a3ddf0ff017234c41a1b0bffb0acf2c361afd5352c2d216e3548c8a702ba2558ab63f0bf2200 + checksum: a3226f7930b635ee7a5e72c8d51a357e799d19cbf9d445710fa39ab13804f79ab1a54b72ea7d8e504659c7dfc50675db974b526142c754398d7413aa4bc30845 languageName: node linkType: hard @@ -2780,6 +2993,15 @@ __metadata: languageName: node linkType: hard +"@types/babel__traverse@npm:^7.0.4": + version: 7.20.5 + resolution: "@types/babel__traverse@npm:7.20.5" + dependencies: + "@babel/types": ^7.20.7 + checksum: 608e0ab4fc31cd47011d98942e6241b34d461608c0c0e153377c5fd822c436c475f1ded76a56bfa76a1adf8d9266b727bbf9bfac90c4cb152c97f30dadc5b7e8 + languageName: node + linkType: hard + "@types/cheerio@npm:*": version: 0.22.29 resolution: "@types/cheerio@npm:0.22.29" @@ -2841,6 +3063,30 @@ __metadata: languageName: node linkType: hard +"@types/eslint@npm:^7.29.0": + version: 7.29.0 + resolution: "@types/eslint@npm:7.29.0" + dependencies: + "@types/estree": "*" + "@types/json-schema": "*" + checksum: df13991c554954353ce8f3bb03e19da6cc71916889443d68d178d4f858b561ba4cc4a4f291c6eb9eebb7f864b12b9b9313051b3a8dfea3e513dadf3188a77bdf + languageName: node + linkType: hard + +"@types/estree@npm:*": + version: 1.0.5 + resolution: "@types/estree@npm:1.0.5" + checksum: dd8b5bed28e6213b7acd0fb665a84e693554d850b0df423ac8076cc3ad5823a6bc26b0251d080bdc545af83179ede51dd3f6fa78cad2c46ed1f29624ddf3e41a + languageName: node + linkType: hard + +"@types/estree@npm:0.0.39": + version: 0.0.39 + resolution: "@types/estree@npm:0.0.39" + checksum: 412fb5b9868f2c418126451821833414189b75cc6bf84361156feed733e3d92ec220b9d74a89e52722e03d5e241b2932732711b7497374a404fad49087adc248 + languageName: node + linkType: hard + "@types/file-saver@npm:2.0.0": version: 2.0.0 resolution: "@types/file-saver@npm:2.0.0" @@ -2858,6 +3104,15 @@ __metadata: languageName: node linkType: hard +"@types/graceful-fs@npm:^4.1.2": + version: 4.1.9 + resolution: "@types/graceful-fs@npm:4.1.9" + dependencies: + "@types/node": "*" + checksum: 79d746a8f053954bba36bd3d94a90c78de995d126289d656fb3271dd9f1229d33f678da04d10bce6be440494a5a73438e2e363e92802d16b8315b051036c5256 + languageName: node + linkType: hard + "@types/history@npm:*": version: 4.7.8 resolution: "@types/history@npm:4.7.8" @@ -2865,6 +3120,13 @@ __metadata: languageName: node linkType: hard +"@types/html-minifier-terser@npm:^5.0.0": + version: 5.1.2 + resolution: "@types/html-minifier-terser@npm:5.1.2" + checksum: 4bca779c44d2aebe4cc4036c5db370abe7466249038e9c5996cb3c192debeff1c75b7a2ab78e5fd2a014ad24ebf0f357f9a174a4298540dc1e1317d43aa69cfa + languageName: node + linkType: hard + "@types/is-image@npm:3.0.0": version: 3.0.0 resolution: "@types/is-image@npm:3.0.0" @@ -2881,6 +3143,13 @@ __metadata: languageName: node linkType: hard +"@types/istanbul-lib-coverage@npm:^2.0.1": + version: 2.0.6 + resolution: "@types/istanbul-lib-coverage@npm:2.0.6" + checksum: 3feac423fd3e5449485afac999dcfcb3d44a37c830af898b689fadc65d26526460bedb889db278e0d4d815a670331796494d073a10ee6e3a6526301fe7415778 + languageName: node + linkType: hard + "@types/istanbul-lib-report@npm:*": version: 3.0.0 resolution: "@types/istanbul-lib-report@npm:3.0.0" @@ -2890,16 +3159,6 @@ __metadata: languageName: node linkType: hard -"@types/istanbul-reports@npm:^1.1.1": - version: 1.1.2 - resolution: "@types/istanbul-reports@npm:1.1.2" - dependencies: - "@types/istanbul-lib-coverage": "*" - "@types/istanbul-lib-report": "*" - checksum: 00866e815d1e68d0a590d691506937b79d8d65ad8eab5ed34dbfee66136c7c0f4ea65327d32046d5fe469f22abea2b294987591dc66365ebc3991f7e413b2d78 - languageName: node - linkType: hard - "@types/istanbul-reports@npm:^3.0.0": version: 3.0.1 resolution: "@types/istanbul-reports@npm:3.0.1" @@ -2926,13 +3185,27 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.7": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.3, @types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.8": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 97ed0cb44d4070aecea772b7b2e2ed971e10c81ec87dd4ecc160322ffa55ff330dace1793489540e3e318d90942064bb697cc0f8989391797792d919737b3b98 + languageName: node + linkType: hard + +"@types/json-schema@npm:^7.0.5": version: 7.0.7 resolution: "@types/json-schema@npm:7.0.7" checksum: ea3b409235862d28122751158f4054e729e31ad844bd7b8b23868f38c518047b1c0e8e4e7cc293e02c31a2fb8cfc8a4506c2de2a745cf78b218e064fb8898cd4 languageName: node linkType: hard +"@types/json5@npm:^0.0.29": + version: 0.0.29 + resolution: "@types/json5@npm:0.0.29" + checksum: e60b153664572116dfea673c5bda7778dbff150498f44f998e34b5886d8afc47f16799280e4b6e241c0472aef1bc36add771c569c68fc5125fc2ae519a3eb9ac + languageName: node + linkType: hard + "@types/jss@npm:^9.5.6": version: 9.5.8 resolution: "@types/jss@npm:9.5.8" @@ -3001,6 +3274,13 @@ __metadata: languageName: node linkType: hard +"@types/prettier@npm:^2.0.0": + version: 2.7.3 + resolution: "@types/prettier@npm:2.7.3" + checksum: 705384209cea6d1433ff6c187c80dcc0b95d99d5c5ce21a46a9a58060c527973506822e428789d842761e0280d25e3359300f017fbe77b9755bc772ab3dc2f83 + languageName: node + linkType: hard + "@types/prop-types@npm:*": version: 15.7.3 resolution: "@types/prop-types@npm:15.7.3" @@ -3180,6 +3460,15 @@ __metadata: languageName: node linkType: hard +"@types/resolve@npm:0.0.8": + version: 0.0.8 + resolution: "@types/resolve@npm:0.0.8" + dependencies: + "@types/node": "*" + checksum: f241bb773ab14b14500623ac3b57c52006ce32b20426b6d8bf2fe5fdc0344f42c77ac0f94ff57b443ae1d320a1a86c62b4e47239f0321699404402fbeb24bad6 + languageName: node + linkType: hard + "@types/scheduler@npm:*": version: 0.16.1 resolution: "@types/scheduler@npm:0.16.1" @@ -3215,10 +3504,17 @@ __metadata: languageName: node linkType: hard -"@types/stack-utils@npm:^1.0.1": - version: 1.0.1 - resolution: "@types/stack-utils@npm:1.0.1" - checksum: 9dc052b575acfeca3f165fb19d87b7b2989d54ed7d64a7eeb0b7587bc5795ef1f2c2b1511a44dcf0831ef35b8ce3486f97fcbfdd50c01f68aa297de31502c9d9 +"@types/source-list-map@npm:*": + version: 0.1.6 + resolution: "@types/source-list-map@npm:0.1.6" + checksum: 9cd294c121f1562062de5d241fe4d10780b1131b01c57434845fe50968e9dcf67ede444591c2b1ad6d3f9b6bc646ac02cc8f51a3577c795f9c64cf4573dcc6b1 + languageName: node + linkType: hard + +"@types/stack-utils@npm:^2.0.0": + version: 2.0.3 + resolution: "@types/stack-utils@npm:2.0.3" + checksum: 72576cc1522090fe497337c2b99d9838e320659ac57fa5560fcbdcbafcf5d0216c6b3a0a8a4ee4fdb3b1f5e3420aa4f6223ab57b82fef3578bec3206425c6cf5 languageName: node linkType: hard @@ -3229,6 +3525,13 @@ __metadata: languageName: node linkType: hard +"@types/tapable@npm:^1, @types/tapable@npm:^1.0.5": + version: 1.0.12 + resolution: "@types/tapable@npm:1.0.12" + checksum: 5312fbc01e0135bd11b44cfea2bf29943807cd9675c10bbed13873ad0e73f656993fb88bb6ceaf05b12a55c570e6acc0267faf59e9c4d2f032fc833bafcf0597 + languageName: node + linkType: hard + "@types/trusted-types@npm:*": version: 2.0.4 resolution: "@types/trusted-types@npm:2.0.4" @@ -3236,6 +3539,15 @@ __metadata: languageName: node linkType: hard +"@types/uglify-js@npm:*": + version: 3.17.5 + resolution: "@types/uglify-js@npm:3.17.5" + dependencies: + source-map: ^0.6.1 + checksum: ffed5d63637c6ea5c155469121ee40d9b652e677e6d9eb07b72ff72bb4029ffad19049a0af6e91a5021bad6c481cff2572fbf6367e319c6885cf1537c20d861d + languageName: node + linkType: hard + "@types/uuid@npm:3.4.4": version: 3.4.4 resolution: "@types/uuid@npm:3.4.4" @@ -3245,19 +3557,35 @@ __metadata: languageName: node linkType: hard -"@types/yargs-parser@npm:*": - version: 20.2.0 - resolution: "@types/yargs-parser@npm:20.2.0" - checksum: 54cf3f8d2c7db47e200e8c96e05b3b33ee554e78d29f3db55f04ca4b86dc6b8ff6b1349f5772268ce2d365cde0a0f4fdd92bf5933c2be2c1ea3f19f0b4599e1f +"@types/webpack-sources@npm:*": + version: 3.2.3 + resolution: "@types/webpack-sources@npm:3.2.3" + dependencies: + "@types/node": "*" + "@types/source-list-map": "*" + source-map: ^0.7.3 + checksum: 7b557f242efaa10e4e3e18cc4171a0c98e22898570caefdd4f7b076fe8534b5abfac92c953c6604658dcb7218507f970230352511840fe9fdea31a9af3b9a906 languageName: node linkType: hard -"@types/yargs@npm:^13.0.0": - version: 13.0.11 - resolution: "@types/yargs@npm:13.0.11" +"@types/webpack@npm:^4.41.8": + version: 4.41.38 + resolution: "@types/webpack@npm:4.41.38" dependencies: - "@types/yargs-parser": "*" - checksum: efcbcccd20eab773970c2f103efaf69901924ab3bfc69cc5603ece0be7626937242b2f952b7ebc3708c121f8507e1d0633eb4cc04843433bf3d8b133b83bb811 + "@types/node": "*" + "@types/tapable": ^1 + "@types/uglify-js": "*" + "@types/webpack-sources": "*" + anymatch: ^3.0.0 + source-map: ^0.6.0 + checksum: d3de65993ef3a7621f75548c2f6f509e8f87f586032238e999743d6067030655c67e38ec5f8b32e04fa5276c83bdfb7a761773bce0e6f28605da87e3fc388e3e + languageName: node + linkType: hard + +"@types/yargs-parser@npm:*": + version: 20.2.0 + resolution: "@types/yargs-parser@npm:20.2.0" + checksum: 54cf3f8d2c7db47e200e8c96e05b3b33ee554e78d29f3db55f04ca4b86dc6b8ff6b1349f5772268ce2d365cde0a0f4fdd92bf5933c2be2c1ea3f19f0b4599e1f languageName: node linkType: hard @@ -3288,14 +3616,15 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/eslint-plugin@npm:^2.10.0": - version: 4.28.0 - resolution: "@typescript-eslint/eslint-plugin@npm:4.28.0" +"@typescript-eslint/eslint-plugin@npm:^4.5.0": + version: 4.33.0 + resolution: "@typescript-eslint/eslint-plugin@npm:4.33.0" dependencies: - "@typescript-eslint/experimental-utils": 4.28.0 - "@typescript-eslint/scope-manager": 4.28.0 + "@typescript-eslint/experimental-utils": 4.33.0 + "@typescript-eslint/scope-manager": 4.33.0 debug: ^4.3.1 functional-red-black-tree: ^1.0.1 + ignore: ^5.1.8 regexpp: ^3.1.0 semver: ^7.3.5 tsutils: ^3.21.0 @@ -3305,66 +3634,107 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: fb52430e3a219e45c014c8a8407ccd2830da45e6fc134d0138b99faf45e580d3ad9a3405cad98726183779d94640366c532e4519783a2a99fe072dc73705b8ad + checksum: d74855d0a5ffe0b2f362ec02fcd9301d39a53fb4155b9bd0cb15a0a31d065143129ebf98df9d86af4b6f74de1d423a4c0d8c0095520844068117453afda5bc4f languageName: node linkType: hard -"@typescript-eslint/experimental-utils@npm:4.28.0": - version: 4.28.0 - resolution: "@typescript-eslint/experimental-utils@npm:4.28.0" +"@typescript-eslint/experimental-utils@npm:4.33.0, @typescript-eslint/experimental-utils@npm:^4.0.1": + version: 4.33.0 + resolution: "@typescript-eslint/experimental-utils@npm:4.33.0" dependencies: "@types/json-schema": ^7.0.7 - "@typescript-eslint/scope-manager": 4.28.0 - "@typescript-eslint/types": 4.28.0 - "@typescript-eslint/typescript-estree": 4.28.0 + "@typescript-eslint/scope-manager": 4.33.0 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/typescript-estree": 4.33.0 eslint-scope: ^5.1.1 eslint-utils: ^3.0.0 peerDependencies: eslint: "*" - checksum: 29bcee0d581ad20043532b6b1fa0c2e844ab35a99aa67478fbb68b7be5889dc8aee1f52b72c3a51d8f4cf57e1f0ac664d92738b3eb5aea9aa8a8c72aa30a74b7 + checksum: f859800ada0884f92db6856f24efcb1d073ac9883ddc2b1aa9339f392215487895bed8447ebce3741e8141bb32e545244abef62b73193ba9a8a0527c523aabae + languageName: node + linkType: hard + +"@typescript-eslint/experimental-utils@npm:^3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/experimental-utils@npm:3.10.1" + dependencies: + "@types/json-schema": ^7.0.3 + "@typescript-eslint/types": 3.10.1 + "@typescript-eslint/typescript-estree": 3.10.1 + eslint-scope: ^5.0.0 + eslint-utils: ^2.0.0 + peerDependencies: + eslint: "*" + checksum: 635cc1afe466088b04901c2bce0e4c3e48bb74668e61e39aa74a485f856c6f9683482350d4b16b3f4c0112ce40cad2c2c427d4fe5e11a3329b3bb93286d4ab26 languageName: node linkType: hard -"@typescript-eslint/parser@npm:^2.10.0": - version: 4.28.0 - resolution: "@typescript-eslint/parser@npm:4.28.0" +"@typescript-eslint/parser@npm:^4.5.0": + version: 4.33.0 + resolution: "@typescript-eslint/parser@npm:4.33.0" dependencies: - "@typescript-eslint/scope-manager": 4.28.0 - "@typescript-eslint/types": 4.28.0 - "@typescript-eslint/typescript-estree": 4.28.0 + "@typescript-eslint/scope-manager": 4.33.0 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/typescript-estree": 4.33.0 debug: ^4.3.1 peerDependencies: eslint: ^5.0.0 || ^6.0.0 || ^7.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 08c167db5c36776a638afe52130e0bf20bfc94598da3f178171cfafb72703fc508b17667b4584cd6bea4c8c6d6922af8f7a45e9a7d6419f83fe2f6c893845d96 + checksum: 102457eae1acd516211098fea081c8a2ed728522bbda7f5a557b6ef23d88970514f9a0f6285d53fca134d3d4d7d17822b5d5e12438d5918df4d1f89cc9e67d57 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:4.28.0": - version: 4.28.0 - resolution: "@typescript-eslint/scope-manager@npm:4.28.0" +"@typescript-eslint/scope-manager@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/scope-manager@npm:4.33.0" dependencies: - "@typescript-eslint/types": 4.28.0 - "@typescript-eslint/visitor-keys": 4.28.0 - checksum: cdab7ef35e18cf2c9a25a4e588cb464bd7e6a3e3f9a7dceaa567fa04202b68901b5c9dc108c3ff7b92215c373274c9d105b8061ae97d2600039345c53d33a4ae + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/visitor-keys": 4.33.0 + checksum: 9a25fb7ba7c725ea7227a24d315b0f6aacbad002e2549a049edf723c1d3615c22f5c301f0d7d615b377f2cdf2f3519d97e79af0c459de6ef8d2aaf0906dff13e + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/types@npm:3.10.1" + checksum: 3ea820d37c2595d457acd6091ffda8b531e5d916e1cce708336bf958aa8869126f95cca3268a724f453ce13be11c5388a0a4143bf09bca51be1020ec46635d92 + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/types@npm:4.33.0" + checksum: 3baae1ca35872421b4eb60f5d3f3f32dc1d513f2ae0a67dee28c7d159fd7a43ed0d11a8a5a0f0c2d38507ffa036fc7c511cb0f18a5e8ac524b3ebde77390ec53 languageName: node linkType: hard -"@typescript-eslint/types@npm:4.28.0": - version: 4.28.0 - resolution: "@typescript-eslint/types@npm:4.28.0" - checksum: 5d167f32e93f5854e78315a3a59beaf45bf9fdc5dc6a01d02c22152c08c8871022b5c41281c5355f44be1f9d36f9d24a67087a5c0dcfeea25477eb5918b5c410 +"@typescript-eslint/typescript-estree@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/typescript-estree@npm:3.10.1" + dependencies: + "@typescript-eslint/types": 3.10.1 + "@typescript-eslint/visitor-keys": 3.10.1 + debug: ^4.1.1 + glob: ^7.1.6 + is-glob: ^4.0.1 + lodash: ^4.17.15 + semver: ^7.3.2 + tsutils: ^3.17.1 + peerDependenciesMeta: + typescript: + optional: true + checksum: 911680da9d26220944f4f8f26f88349917609844fafcff566147cecae37ff0211d66c626eb62a2b24d17fd50d10715f5b0f32b2e7f5d9a88efc46709266d5053 languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:4.28.0": - version: 4.28.0 - resolution: "@typescript-eslint/typescript-estree@npm:4.28.0" +"@typescript-eslint/typescript-estree@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/typescript-estree@npm:4.33.0" dependencies: - "@typescript-eslint/types": 4.28.0 - "@typescript-eslint/visitor-keys": 4.28.0 + "@typescript-eslint/types": 4.33.0 + "@typescript-eslint/visitor-keys": 4.33.0 debug: ^4.3.1 globby: ^11.0.3 is-glob: ^4.0.1 @@ -3373,199 +3743,207 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 680ec9a48cc702eba81a1a9101d6635fac10977c930cdb79a94c975b611c0276cc30e13f41630faeb28446cdcc0afb50bd389042629b35a6dd51b6d6774e0973 + checksum: 2566984390c76bd95f43240057215c068c69769e406e27aba41e9f21fd300074d6772e4983fa58fe61e80eb5550af1548d2e31e80550d92ba1d051bb00fe6f5c + languageName: node + linkType: hard + +"@typescript-eslint/visitor-keys@npm:3.10.1": + version: 3.10.1 + resolution: "@typescript-eslint/visitor-keys@npm:3.10.1" + dependencies: + eslint-visitor-keys: ^1.1.0 + checksum: 0c4825b9829b1c11258a73aaee70d64834ba6d9b24157e7624e80f27f6537f468861d4dd33ad233c13ad2c6520afb9008c0675da6d792f26e82d75d6bfe9b0c6 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:4.28.0": - version: 4.28.0 - resolution: "@typescript-eslint/visitor-keys@npm:4.28.0" +"@typescript-eslint/visitor-keys@npm:4.33.0": + version: 4.33.0 + resolution: "@typescript-eslint/visitor-keys@npm:4.33.0" dependencies: - "@typescript-eslint/types": 4.28.0 + "@typescript-eslint/types": 4.33.0 eslint-visitor-keys: ^2.0.0 - checksum: a2f5cec756946d924e3a4f5e89d600da82d500690575620513eb700e9ab65226f62910a16ed3a2e1e9c46d7171ee6c5f23ff82e222dcd65e4b6e14f712534d71 + checksum: 59953e474ad4610c1aa23b2b1a964445e2c6201521da6367752f37939d854352bbfced5c04ea539274065e012b1337ba3ffa49c2647a240a4e87155378ba9873 languageName: node linkType: hard -"@webassemblyjs/ast@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/ast@npm:1.8.5" +"@webassemblyjs/ast@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/ast@npm:1.9.0" dependencies: - "@webassemblyjs/helper-module-context": 1.8.5 - "@webassemblyjs/helper-wasm-bytecode": 1.8.5 - "@webassemblyjs/wast-parser": 1.8.5 - checksum: eee2593fd09ea888ed5ed8919e681a479f9d997061f97264020c8d4b0be11ab3c4e8646463afd021c8c40f1d92023cad1a09559ccdef6e24fdb4290e021a368b + "@webassemblyjs/helper-module-context": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/wast-parser": 1.9.0 + checksum: 8a9838dc7fdac358aee8daa75eefa35934ab18dafb594092ff7be79c467ebe9dabb2543e58313c905fd802bdcc3cb8320e4e19af7444e49853a7a24e25138f75 languageName: node linkType: hard -"@webassemblyjs/floating-point-hex-parser@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.8.5" - checksum: 68a1ff458355fb6b1553c8f7e2df6d76623bf5ef895f3fc30de620b88d1e68224643c8daf517d19b75d4e10a7f663c038b9912970edcae6f5a4fdb85b630bfc3 +"@webassemblyjs/floating-point-hex-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/floating-point-hex-parser@npm:1.9.0" + checksum: d3aeb19bc30da26f639698daa28e44e0c18d5aa135359ef3c54148e194eec46451a912d0506099d479a71a94bc3eef6ef52d6ec234799528a25a9744789852de languageName: node linkType: hard -"@webassemblyjs/helper-api-error@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-api-error@npm:1.8.5" - checksum: 83e3c62a67f94cc36b2b8c4785aa92c15fc5d95a0e22c4b6c39dace583dd9c47c88bc4dea032a959b511d33db26eeb8de9b7be6f5d343f89ebdbd17c11520827 +"@webassemblyjs/helper-api-error@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-api-error@npm:1.9.0" + checksum: 9179d3148639cc202e89a118145b485cf834613260679a99af6ec487bbc15f238566ca713207394b336160a41bf8c1b75cf2e853b3e96f0cc73c1e5c735b3f64 languageName: node linkType: hard -"@webassemblyjs/helper-buffer@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-buffer@npm:1.8.5" - checksum: 5eeb48b135d5ca013c8876228a3a2ccfba98d87dfe12fcf6921e0acf7a272070f369e4e4e8a7f34f2cf22e8faaade24a39a9bcfba76498f103f051384b0f55b3 +"@webassemblyjs/helper-buffer@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-buffer@npm:1.9.0" + checksum: dcb85f630f8a2e22b7346ad4dd58c3237a2cad1457699423e8fd19592a0bd3eacbc2639178a1b9a873c3ac217bfc7a23a134ff440a099496b590e82c7a4968d5 languageName: node linkType: hard -"@webassemblyjs/helper-code-frame@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-code-frame@npm:1.8.5" +"@webassemblyjs/helper-code-frame@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-code-frame@npm:1.9.0" dependencies: - "@webassemblyjs/wast-printer": 1.8.5 - checksum: 80ca0fdc18c39ba1fe3f139f657f62159b7269ca153f10c5b984f5140a83e3fb8c18565f4443afbce144622b9eb8d16034beb52efc91b69e1e107e15b9f5a6c6 + "@webassemblyjs/wast-printer": 1.9.0 + checksum: a28fa057f7beff0fd14bff716561520f8edb8c9c56c7a5559451e6765acfb70aaeb8af718ea2bd2262e7baeba597545af407e28eb2eff8329235afe8605f20d1 languageName: node linkType: hard -"@webassemblyjs/helper-fsm@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-fsm@npm:1.8.5" - checksum: 5026861c39518cf7f8fa6a88ccad8e251d906130a9ccfe2a49da5eb5321bfdf0861f31e5269f76687259f96cc8143f09a9df73a3836c44cb5445bdc01f77fd91 +"@webassemblyjs/helper-fsm@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-fsm@npm:1.9.0" + checksum: 374cc510c8f5a7a07d4fe9eb7036cc475a96a670b5d25c31f16757ac8295be8d03a2f29657ff53eaefa9e8315670a48824d430ed910e7c1835788ac79f93124e languageName: node linkType: hard -"@webassemblyjs/helper-module-context@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-module-context@npm:1.8.5" +"@webassemblyjs/helper-module-context@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-module-context@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - mamacro: ^0.0.3 - checksum: 519ff898993e9331b21bf22dbb85c91378f5c227e7075a4cd580c8e51dfd1372847c722b2e49564d2609b54e10283d68cad6d243b8a95d7833f60c6eb33a5259 + "@webassemblyjs/ast": 1.9.0 + checksum: 55e8f89c7ea1beaa78fad88403f3753b8413b0f3b6bb32d898ce95078b3e1d1b48ade0919c00b82fc2e3813c0ab6901e415f7a4d4fa9be50944e2431adde75a5 languageName: node linkType: hard -"@webassemblyjs/helper-wasm-bytecode@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.8.5" - checksum: ac560cafe93e5ef07d892cea8ed5f1cb2b7cb8777a335fa92d99068eef650fbc37077e2ac8861bcaed337ac613db477741603554d9784373d41acaeffefd2c01 +"@webassemblyjs/helper-wasm-bytecode@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-wasm-bytecode@npm:1.9.0" + checksum: 280da4df3c556f73a1a02053277f8a4be481de32df4aa21050b015c8f4d27c46af89f0417eb88e486df117e5df4bccffae593f78cb1e79f212d3b3d4f3ed0f04 languageName: node linkType: hard -"@webassemblyjs/helper-wasm-section@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/helper-wasm-section@npm:1.8.5" +"@webassemblyjs/helper-wasm-section@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/helper-wasm-section@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-buffer": 1.8.5 - "@webassemblyjs/helper-wasm-bytecode": 1.8.5 - "@webassemblyjs/wasm-gen": 1.8.5 - checksum: f8af22bf904d43d2700708bcb61ebfe1241cb57a4ef3e1400327c072d43b34bf5a04c39493a5d7691cca0590cec0cb0935cad7111764593cdb0840e637edac9d + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + checksum: b8f7bb45d4194074c82210211a5d3e402a5b5fa63ecae26d2c356ae3978af5a530e91192fb260f32f9d561b18e2828b3da2e2f41c59efadb5f3c6d72446807f0 languageName: node linkType: hard -"@webassemblyjs/ieee754@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/ieee754@npm:1.8.5" +"@webassemblyjs/ieee754@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/ieee754@npm:1.9.0" dependencies: "@xtuc/ieee754": ^1.2.0 - checksum: 20230eb79e4bdf812f49ae73ca145a0a8d0fa1ec8a6353b5a36e57c1955ecc7245f277bfb1bf839e041fff7f300948d938b0672bae9d5764519ed0b6a6aa1bdb + checksum: 7fe4a217ba0f7051e2cfef92919d4a64fac1a63c65411763779bd50907820f33f440255231a474fe3ba03bd1d9ee0328662d1eae3fce4c59b91549d6b62b839b languageName: node linkType: hard -"@webassemblyjs/leb128@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/leb128@npm:1.8.5" +"@webassemblyjs/leb128@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/leb128@npm:1.9.0" dependencies: "@xtuc/long": 4.2.2 - checksum: c41603eba2d4052bf14e9213bfa80534dcbafacc782bd8faef80394cf2a93a4aece465416a5132aff2ec8339381003689850b72899828c236313e3653fb47214 + checksum: 4ca7cbb869530d78d42a414f34ae53249364cb1ecebbfb6ed5d562c2f209fce857502f088822ee82a23876f653a262ddc34ab64e45a7962510a263d39bb3f51a languageName: node linkType: hard -"@webassemblyjs/utf8@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/utf8@npm:1.8.5" - checksum: 6aac4440996a160f268762a3dad1ef4a02f4d06fe3a7a0189556adbbbc34ed9ec54a2eadc2adb0aea2ba3430e9dbe20ab461df4f224eed73c9066904b17013e4 +"@webassemblyjs/utf8@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/utf8@npm:1.9.0" + checksum: e328a30ac8a503bbd015d32e75176e0dedcb45a21d4be051c25dfe89a00035ca7a6dbd8937b442dd5b4b334de3959d4f5fe0b330037bd226a28b9814cd49e84f languageName: node linkType: hard -"@webassemblyjs/wasm-edit@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wasm-edit@npm:1.8.5" +"@webassemblyjs/wasm-edit@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-edit@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-buffer": 1.8.5 - "@webassemblyjs/helper-wasm-bytecode": 1.8.5 - "@webassemblyjs/helper-wasm-section": 1.8.5 - "@webassemblyjs/wasm-gen": 1.8.5 - "@webassemblyjs/wasm-opt": 1.8.5 - "@webassemblyjs/wasm-parser": 1.8.5 - "@webassemblyjs/wast-printer": 1.8.5 - checksum: 7298a60bd4914a7d13bceebce4a130f412056eb40a9d9a27d102bf173a0b369cb0d4be3303abcd08c9482695afe79080e896ace4f2ecabbb0247e2f1829fd4ca + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/helper-wasm-section": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + "@webassemblyjs/wasm-opt": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + "@webassemblyjs/wast-printer": 1.9.0 + checksum: 1997e0c2f4051c33239587fb143242919320bc861a0af03a873c7150a27d6404bd2e063c658193288b0aa88c35aadbe0c4fde601fe642bae0743a8c8eda52717 languageName: node linkType: hard -"@webassemblyjs/wasm-gen@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wasm-gen@npm:1.8.5" +"@webassemblyjs/wasm-gen@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-gen@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-wasm-bytecode": 1.8.5 - "@webassemblyjs/ieee754": 1.8.5 - "@webassemblyjs/leb128": 1.8.5 - "@webassemblyjs/utf8": 1.8.5 - checksum: d861e0233aff09e4841624f6554e32fc3056c232a2b3a9cf92bfcc3f9f34f850e240b6dec70977ae55afd5e5cea3e8d260292cccb1803dc26da4fdcee72b4637 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/ieee754": 1.9.0 + "@webassemblyjs/leb128": 1.9.0 + "@webassemblyjs/utf8": 1.9.0 + checksum: 2456e84e8e6bedb7ab47f6333a0ee170f7ef62842c90862ca787c08528ca8041061f3f8bc257fc2a01bf6e8d1a76fddaddd43418c738f681066e5b50f88fe7df languageName: node linkType: hard -"@webassemblyjs/wasm-opt@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wasm-opt@npm:1.8.5" +"@webassemblyjs/wasm-opt@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-opt@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-buffer": 1.8.5 - "@webassemblyjs/wasm-gen": 1.8.5 - "@webassemblyjs/wasm-parser": 1.8.5 - checksum: 44b18c328b919ba4510d58b4dfe6244edac8c21cd2b6cf7167ad58feb0ddc61217c98521b2f0ffc0e388a0b5469b060a6908e8cc7753ab72945204b4a87dd31b + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-buffer": 1.9.0 + "@webassemblyjs/wasm-gen": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + checksum: 91242205bdbd1aa8045364a5338bfb34880cb2c65f56db8dd19382894209673699fb31a0e5279f25c7e5bcd8f3097d6c9ca84d8969d9613ef2cf166450cc3515 languageName: node linkType: hard -"@webassemblyjs/wasm-parser@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wasm-parser@npm:1.8.5" +"@webassemblyjs/wasm-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wasm-parser@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-api-error": 1.8.5 - "@webassemblyjs/helper-wasm-bytecode": 1.8.5 - "@webassemblyjs/ieee754": 1.8.5 - "@webassemblyjs/leb128": 1.8.5 - "@webassemblyjs/utf8": 1.8.5 - checksum: ea80e9ba6d8f8ba7c3177eda500a41226b5a0373b92a32e8ce81b4562fd4bec37a67ff1a833a378a811307cf1ec4f54f44207c6bbc82fb45709a6cb60d86458f + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-api-error": 1.9.0 + "@webassemblyjs/helper-wasm-bytecode": 1.9.0 + "@webassemblyjs/ieee754": 1.9.0 + "@webassemblyjs/leb128": 1.9.0 + "@webassemblyjs/utf8": 1.9.0 + checksum: 493f6cfc63a5e16073056c81ff0526a9936f461327379ef3c83cc841000e03623b6352704f6bf9f7cb5b3610f0032020a61f9cca78c91b15b8e995854b29c098 languageName: node linkType: hard -"@webassemblyjs/wast-parser@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wast-parser@npm:1.8.5" +"@webassemblyjs/wast-parser@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wast-parser@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/floating-point-hex-parser": 1.8.5 - "@webassemblyjs/helper-api-error": 1.8.5 - "@webassemblyjs/helper-code-frame": 1.8.5 - "@webassemblyjs/helper-fsm": 1.8.5 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/floating-point-hex-parser": 1.9.0 + "@webassemblyjs/helper-api-error": 1.9.0 + "@webassemblyjs/helper-code-frame": 1.9.0 + "@webassemblyjs/helper-fsm": 1.9.0 "@xtuc/long": 4.2.2 - checksum: ec0b28f0c558950024521808c1e12b4597023b0ef914aed0eb9078bcb4daaa34555a46efe35406b8edb899b008782b1a43d96c6485c45e98ce9745fe17196817 + checksum: 705dd48fbbceec7f6bed299b8813631b242fd9312f9594dbb2985dda86c9688048692357d684f6080fc2c5666287cefaa26b263d01abadb6a9049d4c8978b9db languageName: node linkType: hard -"@webassemblyjs/wast-printer@npm:1.8.5": - version: 1.8.5 - resolution: "@webassemblyjs/wast-printer@npm:1.8.5" +"@webassemblyjs/wast-printer@npm:1.9.0": + version: 1.9.0 + resolution: "@webassemblyjs/wast-printer@npm:1.9.0" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/wast-parser": 1.8.5 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/wast-parser": 1.9.0 "@xtuc/long": 4.2.2 - checksum: 7c53f5f694b9820cef5e58653a85f5e9b0eba4e59013a2e0fcf3562d7e70501b0202d73ebadbd14b5845ecf958e3639bdde5a197a4245dded722f2015ec45e2a + checksum: 3d1e1b2e84745a963f69acd1c02425b321dd2e608e11dabc467cae0c9a808962bc769ec9afc46fbcea7188cc1e47d72370da762d258f716fb367cb1a7865c54b languageName: node linkType: hard @@ -3583,10 +3961,10 @@ __metadata: languageName: node linkType: hard -"abab@npm:^2.0.0": - version: 2.0.5 - resolution: "abab@npm:2.0.5" - checksum: 0ec951b46d5418c2c2f923021ec193eaebdb4e802ffd5506286781b454be722a13a8430f98085cd3e204918401d9130ec6cc8f5ae19be315b3a0e857d83196e1 +"abab@npm:^2.0.3, abab@npm:^2.0.5": + version: 2.0.6 + resolution: "abab@npm:2.0.6" + checksum: 6ffc1af4ff315066c62600123990d87551ceb0aafa01e6539da77b0f5987ac7019466780bf480f1787576d4385e3690c81ccc37cfda12819bf510b8ab47e5a3e languageName: node linkType: hard @@ -3617,42 +3995,33 @@ __metadata: languageName: node linkType: hard -"acorn-globals@npm:^4.1.0, acorn-globals@npm:^4.3.0": - version: 4.3.4 - resolution: "acorn-globals@npm:4.3.4" +"acorn-globals@npm:^6.0.0": + version: 6.0.0 + resolution: "acorn-globals@npm:6.0.0" dependencies: - acorn: ^6.0.1 - acorn-walk: ^6.0.1 - checksum: c31bfde102d8a104835e9591c31dd037ec771449f9c86a6b1d2ac3c7c336694f828cfabba7687525b094f896a854affbf1afe6e1b12c0d998be6bab5d49c9663 + acorn: ^7.1.1 + acorn-walk: ^7.1.1 + checksum: 72d95e5b5e585f9acd019b993ab8bbba68bb3cbc9d9b5c1ebb3c2f1fe5981f11deababfb4949f48e6262f9c57878837f5958c0cca396f81023814680ca878042 languageName: node linkType: hard -"acorn-jsx@npm:^5.2.0": - version: 5.3.1 - resolution: "acorn-jsx@npm:5.3.1" +"acorn-jsx@npm:^5.3.1": + version: 5.3.2 + resolution: "acorn-jsx@npm:5.3.2" peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - checksum: daf441a9d7b59c0ea1f7fe2934c48aca604a007455129ce35fa62ec3d4c8363e2efc2d4da636d18ce0049979260ba07d8b42bc002ae95182916d2c90901529c2 - languageName: node - linkType: hard - -"acorn-walk@npm:^6.0.1": - version: 6.2.0 - resolution: "acorn-walk@npm:6.2.0" - checksum: ea241a5d96338f1e8030aafae72a91ff0ec4360e2775e44a2fdb2eb618b07fc309e000a5126056631ac7f00fe8bd9bbd23fcb6d018eee4ba11086eb36c1b2e61 + checksum: c3d3b2a89c9a056b205b69530a37b972b404ee46ec8e5b341666f9513d3163e2a4f214a71f4dfc7370f5a9c07472d2fd1c11c91c3f03d093e37637d95da98950 languageName: node linkType: hard -"acorn@npm:^5.5.3": - version: 5.7.4 - resolution: "acorn@npm:5.7.4" - bin: - acorn: bin/acorn - checksum: f51392a4d25c7705fadb890f784c59cde4ac1c5452ccd569fa59bd2191b7951b4a6398348ab7ea08a54f0bc0a56c13776710f4e1bae9de441e4d33e2015ad1e0 +"acorn-walk@npm:^7.1.1": + version: 7.2.0 + resolution: "acorn-walk@npm:7.2.0" + checksum: 9252158a79b9d92f1bc0dd6acc0fcfb87a67339e84bcc301bb33d6078936d27e35d606b4d35626d2962cd43c256d6f27717e70cbe15c04fff999ab0b2260b21f languageName: node linkType: hard -"acorn@npm:^6.0.1, acorn@npm:^6.0.4, acorn@npm:^6.2.1": +"acorn@npm:^6.4.1": version: 6.4.2 resolution: "acorn@npm:6.4.2" bin: @@ -3661,7 +4030,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^7.1.1": +"acorn@npm:^7.1.0, acorn@npm:^7.1.1, acorn@npm:^7.4.0": version: 7.4.1 resolution: "acorn@npm:7.4.1" bin: @@ -3670,6 +4039,15 @@ __metadata: languageName: node linkType: hard +"acorn@npm:^8.2.4, acorn@npm:^8.8.2": + version: 8.11.3 + resolution: "acorn@npm:8.11.3" + bin: + acorn: bin/acorn + checksum: 76d8e7d559512566b43ab4aadc374f11f563f0a9e21626dd59cb2888444e9445923ae9f3699972767f18af61df89cd89f5eaaf772d1327b055b45cb829b4a88c + languageName: node + linkType: hard + "acorn@npm:^8.5.0": version: 8.7.0 resolution: "acorn@npm:8.7.0" @@ -3772,7 +4150,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.1.0, ajv@npm:^6.1.1, ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4": +"ajv@npm:^6.1.0, ajv@npm:^6.1.1, ajv@npm:^6.10.0, ajv@npm:^6.10.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -3784,6 +4162,18 @@ __metadata: languageName: node linkType: hard +"ajv@npm:^8.0.1": + version: 8.12.0 + resolution: "ajv@npm:8.12.0" + dependencies: + fast-deep-equal: ^3.1.1 + json-schema-traverse: ^1.0.0 + require-from-string: ^2.0.2 + uri-js: ^4.2.2 + checksum: 4dc13714e316e67537c8b31bc063f99a1d9d9a497eb4bbd55191ac0dcd5e4985bbb71570352ad6f1e76684fb6d790928f96ba3b2d4fd6e10024be9612fe3f001 + languageName: node + linkType: hard + "alphanum-sort@npm:^1.0.0": version: 1.0.2 resolution: "alphanum-sort@npm:1.0.2" @@ -3791,13 +4181,6 @@ __metadata: languageName: node linkType: hard -"amdefine@npm:>=0.0.4": - version: 1.0.1 - resolution: "amdefine@npm:1.0.1" - checksum: 9d4e15b94641643a9385b2841b4cb2bcf4e8e2f741ea4bd475c93ad7bab261ad4ed827a32e9c549b38b98759c4526c173ae4e6dde8caeb75ee5cebedc9863762 - languageName: node - linkType: hard - "ansi-colors@npm:^3.0.0": version: 3.2.4 resolution: "ansi-colors@npm:3.2.4" @@ -3812,14 +4195,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^3.0.0": - version: 3.2.0 - resolution: "ansi-escapes@npm:3.2.0" - checksum: 0f94695b677ea742f7f1eed961f7fd8d05670f744c6ad1f8f635362f6681dcfbc1575cb05b43abc7bb6d67e25a75fb8c7ea8f2a57330eb2c76b33f18cb2cef0a - languageName: node - linkType: hard - -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -3828,7 +4204,7 @@ __metadata: languageName: node linkType: hard -"ansi-html@npm:0.0.7": +"ansi-html@npm:0.0.7, ansi-html@npm:^0.0.7": version: 0.0.7 resolution: "ansi-html@npm:0.0.7" bin: @@ -3844,14 +4220,7 @@ __metadata: languageName: node linkType: hard -"ansi-regex@npm:^3.0.0": - version: 3.0.1 - resolution: "ansi-regex@npm:3.0.1" - checksum: 09daf180c5f59af9850c7ac1bd7fda85ba596cc8cbeb210826e90755f06c818af86d9fa1e6e8322fab2c3b9e9b03f56c537b42241139f824dd75066a1e7257cc - languageName: node - linkType: hard - -"ansi-regex@npm:^4.0.0, ansi-regex@npm:^4.1.0": +"ansi-regex@npm:^4.1.0": version: 4.1.1 resolution: "ansi-regex@npm:4.1.1" checksum: b1a6ee44cb6ecdabaa770b2ed500542714d4395d71c7e5c25baa631f680fb2ad322eb9ba697548d498a6fd366949fc8b5bfcf48d49a32803611f648005b01888 @@ -3865,13 +4234,6 @@ __metadata: languageName: node linkType: hard -"ansi-styles@npm:^2.2.1": - version: 2.2.1 - resolution: "ansi-styles@npm:2.2.1" - checksum: ebc0e00381f2a29000d1dac8466a640ce11943cef3bda3cd0020dc042e31e1058ab59bf6169cd794a54c3a7338a61ebc404b7c91e004092dd20e028c432c9c2c - languageName: node - linkType: hard - "ansi-styles@npm:^3.2.0, ansi-styles@npm:^3.2.1": version: 3.2.1 resolution: "ansi-styles@npm:3.2.1" @@ -3900,6 +4262,16 @@ __metadata: languageName: node linkType: hard +"anymatch@npm:^3.0.0, anymatch@npm:^3.0.3": + version: 3.1.3 + resolution: "anymatch@npm:3.1.3" + dependencies: + normalize-path: ^3.0.0 + picomatch: ^2.0.4 + checksum: 3e044fd6d1d26545f235a9fe4d7a534e2029d8e59fa7fd9f2a6eb21230f6b5380ea1eaf55136e60cbf8e613544b3b766e7a6fa2102e2a3a117505466e3025dc2 + languageName: node + linkType: hard + "anymatch@npm:~3.1.2": version: 3.1.2 resolution: "anymatch@npm:3.1.2" @@ -3931,16 +4303,6 @@ __metadata: languageName: node linkType: hard -"are-we-there-yet@npm:^2.0.0": - version: 2.0.0 - resolution: "are-we-there-yet@npm:2.0.0" - dependencies: - delegates: ^1.0.0 - readable-stream: ^3.6.0 - checksum: 6c80b4fd04ecee6ba6e737e0b72a4b41bdc64b7d279edfc998678567ff583c8df27e27523bc789f2c99be603ffa9eaa612803da1d886962d2086e7ff6fa90c7c - languageName: node - linkType: hard - "are-we-there-yet@npm:^3.0.0": version: 3.0.0 resolution: "are-we-there-yet@npm:3.0.0" @@ -3960,13 +4322,12 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^3.0.0": - version: 3.0.0 - resolution: "aria-query@npm:3.0.0" +"aria-query@npm:^5.3.0": + version: 5.3.0 + resolution: "aria-query@npm:5.3.0" dependencies: - ast-types-flow: 0.0.7 - commander: ^2.11.0 - checksum: 52861d7d31321a23f27e5f95a437ddafd20e5eee03ff6e4319eeb1e98dce103f03ccaea34acb5bf2810580f71a9ac1658200fa3d49435279e99df2908f213f1b + dequal: ^2.0.3 + checksum: 305bd73c76756117b59aba121d08f413c7ff5e80fa1b98e217a3443fcddb9a232ee790e24e432b59ae7625aebcf4c47cb01c2cac872994f0b426f5bdfcd96ba9 languageName: node linkType: hard @@ -3998,17 +4359,13 @@ __metadata: languageName: node linkType: hard -"array-equal@npm:^1.0.0": - version: 1.0.0 - resolution: "array-equal@npm:1.0.0" - checksum: 3f68045806357db9b2fa1ad583e42a659de030633118a0cd35ee4975cb20db3b9a3d36bbec9b5afe70011cf989eefd215c12fe0ce08c498f770859ca6e70688a - languageName: node - linkType: hard - -"array-find-index@npm:^1.0.1": - version: 1.0.2 - resolution: "array-find-index@npm:1.0.2" - checksum: aac128bf369e1ac6c06ff0bb330788371c0e256f71279fb92d745e26fb4b9db8920e485b4ec25e841c93146bf71a34dcdbcefa115e7e0f96927a214d237b7081 +"array-buffer-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "array-buffer-byte-length@npm:1.0.1" + dependencies: + call-bind: ^1.0.5 + is-array-buffer: ^3.0.4 + checksum: 53524e08f40867f6a9f35318fafe467c32e45e9c682ba67b11943e167344d2febc0f6977a17e699b05699e805c3e8f073d876f8bbf1b559ed494ad2cd0fae09e languageName: node linkType: hard @@ -4033,16 +4390,17 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.0.3, array-includes@npm:^3.1.1": - version: 3.1.3 - resolution: "array-includes@npm:3.1.3" +"array-includes@npm:^3.1.6, array-includes@npm:^3.1.7": + version: 3.1.8 + resolution: "array-includes@npm:3.1.8" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - es-abstract: ^1.18.0-next.2 - get-intrinsic: ^1.1.1 - is-string: ^1.0.5 - checksum: eaab8812412b5ec921c8fe678a9d61f501b12f6c72e271e0e8652fe7f4145276cc7ad79ff303ac4ed69cbf5135155bfb092b1b6d552e423e75106d1c887da150 + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.4 + is-string: ^1.0.7 + checksum: eb39ba5530f64e4d8acab39297c11c1c5be2a4ea188ab2b34aba5fb7224d918f77717a9d57a3e2900caaa8440e59431bdaf5c974d5212ef65d97f132e38e2d91 languageName: node linkType: hard @@ -4099,7 +4457,35 @@ __metadata: languageName: node linkType: hard -"array.prototype.flat@npm:^1.2.1, array.prototype.flat@npm:^1.2.3": +"array.prototype.findlast@npm:^1.2.4": + version: 1.2.5 + resolution: "array.prototype.findlast@npm:1.2.5" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-shim-unscopables: ^1.0.2 + checksum: 83ce4ad95bae07f136d316f5a7c3a5b911ac3296c3476abe60225bc4a17938bf37541972fcc37dd5adbc99cbb9c928c70bbbfc1c1ce549d41a415144030bb446 + languageName: node + linkType: hard + +"array.prototype.findlastindex@npm:^1.2.3": + version: 1.2.5 + resolution: "array.prototype.findlastindex@npm:1.2.5" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-shim-unscopables: ^1.0.2 + checksum: 2c81cff2a75deb95bf1ed89b6f5f2bfbfb882211e3b7cc59c3d6b87df774cd9d6b36949a8ae39ac476e092c1d4a4905f5ee11a86a456abb10f35f8211ae4e710 + languageName: node + linkType: hard + +"array.prototype.flat@npm:^1.2.3": version: 1.2.4 resolution: "array.prototype.flat@npm:1.2.4" dependencies: @@ -4110,6 +4496,71 @@ __metadata: languageName: node linkType: hard +"array.prototype.flat@npm:^1.3.1, array.prototype.flat@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flat@npm:1.3.2" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: 5d6b4bf102065fb3f43764bfff6feb3295d372ce89591e6005df3d0ce388527a9f03c909af6f2a973969a4d178ab232ffc9236654149173e0e187ec3a1a6b87b + languageName: node + linkType: hard + +"array.prototype.flatmap@npm:^1.3.2": + version: 1.3.2 + resolution: "array.prototype.flatmap@npm:1.3.2" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: ce09fe21dc0bcd4f30271f8144083aa8c13d4639074d6c8dc82054b847c7fc9a0c97f857491f4da19d4003e507172a78f4bcd12903098adac8b9cd374f734be3 + languageName: node + linkType: hard + +"array.prototype.toreversed@npm:^1.1.2": + version: 1.1.2 + resolution: "array.prototype.toreversed@npm:1.1.2" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + es-shim-unscopables: ^1.0.0 + checksum: 58598193426282155297bedf950dc8d464624a0d81659822fb73124286688644cb7e0e4927a07f3ab2daaeb6617b647736cc3a5e6ca7ade5bb8e573b284e6240 + languageName: node + linkType: hard + +"array.prototype.tosorted@npm:^1.1.3": + version: 1.1.3 + resolution: "array.prototype.tosorted@npm:1.1.3" + dependencies: + call-bind: ^1.0.5 + define-properties: ^1.2.1 + es-abstract: ^1.22.3 + es-errors: ^1.1.0 + es-shim-unscopables: ^1.0.2 + checksum: 555e8808086bbde9e634c5dc5a8c0a2f1773075447b43b2fa76ab4f94f4e90f416d2a4f881024e1ce1a2931614caf76cd6b408af901c9d7cd13061d0d268f5af + languageName: node + linkType: hard + +"arraybuffer.prototype.slice@npm:^1.0.3": + version: 1.0.3 + resolution: "arraybuffer.prototype.slice@npm:1.0.3" + dependencies: + array-buffer-byte-length: ^1.0.1 + call-bind: ^1.0.5 + define-properties: ^1.2.1 + es-abstract: ^1.22.3 + es-errors: ^1.2.1 + get-intrinsic: ^1.2.3 + is-array-buffer: ^3.0.4 + is-shared-array-buffer: ^1.0.2 + checksum: 352259cba534dcdd969c92ab002efd2ba5025b2e3b9bead3973150edbdf0696c629d7f4b3f061c5931511e8207bdc2306da614703c820b45dabce39e3daf7e3e + languageName: node + linkType: hard + "arrify@npm:^1.0.1": version: 1.0.1 resolution: "arrify@npm:1.0.1" @@ -4117,6 +4568,13 @@ __metadata: languageName: node linkType: hard +"arrify@npm:^2.0.1": + version: 2.0.1 + resolution: "arrify@npm:2.0.1" + checksum: 067c4c1afd182806a82e4c1cb8acee16ab8b5284fbca1ce29408e6e91281c36bb5b612f6ddfbd40a0f7a7e0c75bf2696eb94c027f6e328d6e9c52465c98e4209 + languageName: node + linkType: hard + "arvados-workbench-2@workspace:.": version: 0.0.0-use.local resolution: "arvados-workbench-2@workspace:." @@ -4162,10 +4620,10 @@ __metadata: "@types/shell-escape": ^0.2.0 "@types/sinon": 7.5 "@types/uuid": 3.4.4 - axios: ^0.21.1 + axios: ^0.28.1 axios-mock-adapter: 1.17.0 bootstrap: ^5.3.2 - caniuse-lite: 1.0.30001606 + caniuse-lite: 1.0.30001612 classnames: 2.2.6 cwlts: 1.15.29 cypress: ^13.6.6 @@ -4192,7 +4650,6 @@ __metadata: mime: ^3.0.0 moment: ^2.29.4 node-sass: ^9.0.0 - node-sass-chokidar: ^2.0.0 parse-duration: 0.4.4 prop-types: 15.7.2 query-string: 6.9.0 @@ -4210,7 +4667,7 @@ __metadata: react-router-dom: 4.3.1 react-router-redux: 5.0.0-alpha.9 react-rte: ^0.16.5 - react-scripts: 3.4.4 + react-scripts: 4.0.1 react-splitter-layout: 3.0.1 react-transition-group: 2.5.0 react-virtualized-auto-sizer: 1.0.2 @@ -4300,17 +4757,10 @@ __metadata: languageName: node linkType: hard -"ast-types-flow@npm:0.0.7, ast-types-flow@npm:^0.0.7": - version: 0.0.7 - resolution: "ast-types-flow@npm:0.0.7" - checksum: a26dcc2182ffee111cad7c471759b0bda22d3b7ebacf27c348b22c55f16896b18ab0a4d03b85b4020dce7f3e634b8f00b593888f622915096ea1927fa51866c4 - languageName: node - linkType: hard - -"astral-regex@npm:^1.0.0": - version: 1.0.0 - resolution: "astral-regex@npm:1.0.0" - checksum: 93417fc0879531cd95ace2560a54df865c9461a3ac0714c60cbbaa5f1f85d2bee85489e78d82f70b911b71ac25c5f05fc5a36017f44c9bb33c701bee229ff848 +"ast-types-flow@npm:^0.0.8": + version: 0.0.8 + resolution: "ast-types-flow@npm:0.0.8" + checksum: 0a64706609a179233aac23817837abab614f3548c252a2d3d79ea1e10c74aa28a0846e11f466cf72771b6ed8713abc094dcf8c40c3ec4207da163efa525a94a8 languageName: node linkType: hard @@ -4414,6 +4864,15 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.7": + version: 1.0.7 + resolution: "available-typed-arrays@npm:1.0.7" + dependencies: + possible-typed-array-names: ^1.0.0 + checksum: 1aa3ffbfe6578276996de660848b6e95669d9a95ad149e3dd0c0cda77db6ee1dbd9d1dd723b65b6d277b882dd0c4b91a654ae9d3cf9e1254b7e93e4908d78fd3 + languageName: node + linkType: hard + "aws-sign2@npm:~0.7.0": version: 0.7.0 resolution: "aws-sign2@npm:0.7.0" @@ -4428,6 +4887,13 @@ __metadata: languageName: node linkType: hard +"axe-core@npm:=4.7.0": + version: 4.7.0 + resolution: "axe-core@npm:4.7.0" + checksum: f086bcab42be1761ba2b0b127dec350087f4c3a853bba8dd58f69d898cefaac31a1561da23146f6f3c07954c76171d1f2ce460e555e052d2b02cd79af628fa4a + languageName: node + linkType: hard + "axios-mock-adapter@npm:1.17.0": version: 1.17.0 resolution: "axios-mock-adapter@npm:1.17.0" @@ -4439,34 +4905,27 @@ __metadata: languageName: node linkType: hard -"axios@npm:^0.21.1": - version: 0.21.4 - resolution: "axios@npm:0.21.4" +"axios@npm:^0.28.1": + version: 0.28.1 + resolution: "axios@npm:0.28.1" dependencies: - follow-redirects: ^1.14.0 - checksum: 44245f24ac971e7458f3120c92f9d66d1fc695e8b97019139de5b0cc65d9b8104647db01e5f46917728edfc0cfd88eb30fc4c55e6053eef4ace76768ce95ff3c - languageName: node - linkType: hard - -"axobject-query@npm:^2.0.2": - version: 2.2.0 - resolution: "axobject-query@npm:2.2.0" - checksum: 96b8c7d807ca525f41ad9b286186e2089b561ba63a6d36c3e7d73dc08150714660995c7ad19cda05784458446a0793b45246db45894631e13853f48c1aa3117f + follow-redirects: ^1.15.0 + form-data: ^4.0.0 + proxy-from-env: ^1.1.0 + checksum: 5115a38d79064d07437c5a28f15841e3607634040e3120ec06a2c4367a7d07cf213b16496eab53b6f58ebc5fb377a440ba9ed4782529b14449a1e285734bfb54 languageName: node linkType: hard -"babel-code-frame@npm:^6.22.0": - version: 6.26.0 - resolution: "babel-code-frame@npm:6.26.0" +"axobject-query@npm:^3.2.1": + version: 3.2.1 + resolution: "axobject-query@npm:3.2.1" dependencies: - chalk: ^1.1.3 - esutils: ^2.0.2 - js-tokens: ^3.0.2 - checksum: 9410c3d5a921eb02fa409675d1a758e493323a49e7b9dddb7a2a24d47e61d39ab1129dd29f9175836eac9ce8b1d4c0a0718fcdc57ce0b865b529fd250dbab313 + dequal: ^2.0.3 + checksum: a94047e702b57c91680e6a952ec4a1aaa2cfd0d80ead76bc8c954202980d8c51968a6ea18b4d8010e8e2cf95676533d8022a8ebba9abc1dfe25686721df26fd2 languageName: node linkType: hard -"babel-eslint@npm:10.1.0": +"babel-eslint@npm:^10.1.0": version: 10.1.0 resolution: "babel-eslint@npm:10.1.0" dependencies: @@ -4491,20 +4950,21 @@ __metadata: languageName: node linkType: hard -"babel-jest@npm:^24.9.0": - version: 24.9.0 - resolution: "babel-jest@npm:24.9.0" +"babel-jest@npm:^26.6.0, babel-jest@npm:^26.6.3": + version: 26.6.3 + resolution: "babel-jest@npm:26.6.3" dependencies: - "@jest/transform": ^24.9.0 - "@jest/types": ^24.9.0 - "@types/babel__core": ^7.1.0 - babel-plugin-istanbul: ^5.1.0 - babel-preset-jest: ^24.9.0 - chalk: ^2.4.2 - slash: ^2.0.0 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/babel__core": ^7.1.7 + babel-plugin-istanbul: ^6.0.0 + babel-preset-jest: ^26.6.2 + chalk: ^4.0.0 + graceful-fs: ^4.2.4 + slash: ^3.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: 205f0d701a202edb483a1f8cc79557f777d20df42656f1a1c2e7ef368f8f53f9d4c4af08ea812d98b61ab12cc5f146db4573a301880770d1dc5748624cc51711 + checksum: 5917233f0d381e719e195b69b81e46da90293432d10288d79f8f59b8f3f9ac030e14701f3d9f90893fb739481df1d132446f1b983d841e65e2623775db100897 languageName: node linkType: hard @@ -4519,94 +4979,89 @@ __metadata: schema-utils: ^2.6.5 peerDependencies: "@babel/core": ^7.0.0 - webpack: ">=2" - checksum: fdbcae91cc43366206320a1cbe40d358a64ba2dfaa561fbd690efe0db6256c9d27ab7600f7c84041fbc4c2a6f0279175b1f8d1fa5ed17ec30bbd734da84a1bc0 - languageName: node - linkType: hard - -"babel-plugin-dynamic-import-node@npm:^2.3.3": - version: 2.3.3 - resolution: "babel-plugin-dynamic-import-node@npm:2.3.3" - dependencies: - object.assign: ^4.1.0 - checksum: c9d24415bcc608d0db7d4c8540d8002ac2f94e2573d2eadced137a29d9eab7e25d2cbb4bc6b9db65cf6ee7430f7dd011d19c911a9a778f0533b4a05ce8292c9b + webpack: ">=2" + checksum: fdbcae91cc43366206320a1cbe40d358a64ba2dfaa561fbd690efe0db6256c9d27ab7600f7c84041fbc4c2a6f0279175b1f8d1fa5ed17ec30bbd734da84a1bc0 languageName: node linkType: hard -"babel-plugin-istanbul@npm:^5.1.0": - version: 5.2.0 - resolution: "babel-plugin-istanbul@npm:5.2.0" +"babel-plugin-istanbul@npm:^6.0.0": + version: 6.1.1 + resolution: "babel-plugin-istanbul@npm:6.1.1" dependencies: "@babel/helper-plugin-utils": ^7.0.0 - find-up: ^3.0.0 - istanbul-lib-instrument: ^3.3.0 - test-exclude: ^5.2.3 - checksum: 46e31a53d1c08a4b738c988871e94dd83e534b3d49248c45c9e63d04d221aa787d8c4f32576e1fade26dbab7cabeae665cbf5eb067aaef74500048dfef365c80 + "@istanbuljs/load-nyc-config": ^1.0.0 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-instrument: ^5.0.4 + test-exclude: ^6.0.0 + checksum: cb4fd95738219f232f0aece1116628cccff16db891713c4ccb501cddbbf9272951a5df81f2f2658dfdf4b3e7b236a9d5cbcf04d5d8c07dd5077297339598061a languageName: node linkType: hard -"babel-plugin-jest-hoist@npm:^24.9.0": - version: 24.9.0 - resolution: "babel-plugin-jest-hoist@npm:24.9.0" +"babel-plugin-jest-hoist@npm:^26.6.2": + version: 26.6.2 + resolution: "babel-plugin-jest-hoist@npm:26.6.2" dependencies: + "@babel/template": ^7.3.3 + "@babel/types": ^7.3.3 + "@types/babel__core": ^7.0.0 "@types/babel__traverse": ^7.0.6 - checksum: 9f0d23fcf94448e302e201665d7232303a548107adf545590b09f22a747755387cb9dc676d22884a298b17d11ede5401436e1b70fa574eee3efa61ad1230c8e6 + checksum: abe3732fdf20f96e91cbf788a54d776b30bd7a6054cb002a744d7071c656813e26e77a780dc2a6f6b197472897e220836cd907bda3fadb9d0481126bfd6c3783 languageName: node linkType: hard -"babel-plugin-macros@npm:2.8.0": - version: 2.8.0 - resolution: "babel-plugin-macros@npm:2.8.0" +"babel-plugin-macros@npm:^3.1.0": + version: 3.1.0 + resolution: "babel-plugin-macros@npm:3.1.0" dependencies: - "@babel/runtime": ^7.7.2 - cosmiconfig: ^6.0.0 - resolve: ^1.12.0 - checksum: 59b09a21cf3ae1e14186c1b021917d004b49b953824b24953a54c6502da79e8051d4ac31cfd4a0ae7f6ea5ddf1f7edd93df4895dd3c3982a5b2431859c2889ac + "@babel/runtime": ^7.12.5 + cosmiconfig: ^7.0.0 + resolve: ^1.19.0 + checksum: 765de4abebd3e4688ebdfbff8571ddc8cd8061f839bb6c3e550b0344a4027b04c60491f843296ce3f3379fb356cc873d57a9ee6694262547eb822c14a25be9a6 languageName: node linkType: hard -"babel-plugin-named-asset-import@npm:^0.3.6": - version: 0.3.7 - resolution: "babel-plugin-named-asset-import@npm:0.3.7" +"babel-plugin-named-asset-import@npm:^0.3.7": + version: 0.3.8 + resolution: "babel-plugin-named-asset-import@npm:0.3.8" peerDependencies: "@babel/core": ^7.1.0 - checksum: 4c9a42a2762f3d596a09105d05991525a0553d095030459d0f71449b023801ccc43e90fa20b618c52283dc61ca528a4a59df244e5b1dd583867786088eb473b7 + checksum: d1e58df8cb75d91d070feea31087bc989906d3465144bde7e9f3c3690b514a90a55d3aebf3e65e76c5d4c743ecedde5f640f09f43a21fa60f1a5d413cb3f7a67 languageName: node linkType: hard -"babel-plugin-polyfill-corejs2@npm:^0.2.2": - version: 0.2.2 - resolution: "babel-plugin-polyfill-corejs2@npm:0.2.2" +"babel-plugin-polyfill-corejs2@npm:^0.4.10": + version: 0.4.10 + resolution: "babel-plugin-polyfill-corejs2@npm:0.4.10" dependencies: - "@babel/compat-data": ^7.13.11 - "@babel/helper-define-polyfill-provider": ^0.2.2 - semver: ^6.1.1 + "@babel/compat-data": ^7.22.6 + "@babel/helper-define-polyfill-provider": ^0.6.1 + semver: ^6.3.1 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: eee45ecce743e06840d29936a7f4a9f9eca19552ba010e9f3676c6a2697ab815230f39953296b72f09665de0e8fffe260e52b348011a9ddba36cfa7eec6f8c51 + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 2c0e4868789152f50db306f4957fa7934876cefb51d5d86436595f0b091539e45ce0e9c0125b5db2d71f913b29cd48ae76b8e942ba28fcf2273e084f54664a1c languageName: node linkType: hard -"babel-plugin-polyfill-corejs3@npm:^0.2.2": - version: 0.2.3 - resolution: "babel-plugin-polyfill-corejs3@npm:0.2.3" +"babel-plugin-polyfill-corejs3@npm:^0.10.1, babel-plugin-polyfill-corejs3@npm:^0.10.4": + version: 0.10.4 + resolution: "babel-plugin-polyfill-corejs3@npm:0.10.4" dependencies: - "@babel/helper-define-polyfill-provider": ^0.2.2 - core-js-compat: ^3.14.0 + "@babel/helper-define-polyfill-provider": ^0.6.1 + core-js-compat: ^3.36.1 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: e390c5317b35808633d32db2c1718aef6af788df148adc6fa54e56d2266896ad2da2d200163f392e06ae1ebd1a0feaeaf18d7a337dea70387429618898b90a68 + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: b96a54495f7cc8b3797251c8c15f5ed015edddc3110fc122f6b32c94bec33af1e8bc56fa99091808f500bde0cccaaa266889cdc5935d9e6e9cf09898214f02dd languageName: node linkType: hard -"babel-plugin-polyfill-regenerator@npm:^0.2.2": - version: 0.2.2 - resolution: "babel-plugin-polyfill-regenerator@npm:0.2.2" +"babel-plugin-polyfill-regenerator@npm:^0.6.1": + version: 0.6.1 + resolution: "babel-plugin-polyfill-regenerator@npm:0.6.1" dependencies: - "@babel/helper-define-polyfill-provider": ^0.2.2 + "@babel/helper-define-polyfill-provider": ^0.6.1 peerDependencies: - "@babel/core": ^7.0.0-0 - checksum: 3e32e318fd91d65c3af2bb363189f00d3839f07a73a08813b553553e07da205162091b428dd5b6ffb6ea4caf531ff43ebc54197b0a5a9dc2fc5c7e9a650e946d + "@babel/core": ^7.4.0 || ^8.0.0-0 <8.0.0 + checksum: 9df4a8e9939dd419fed3d9ea26594b4479f2968f37c225e1b2aa463001d7721f5537740e6622909d2a570b61cec23256924a1701404fc9d6fd4474d3e845cedb languageName: node linkType: hard @@ -4627,45 +5082,68 @@ __metadata: languageName: node linkType: hard -"babel-plugin-transform-react-remove-prop-types@npm:0.4.24": +"babel-plugin-transform-react-remove-prop-types@npm:^0.4.24": version: 0.4.24 resolution: "babel-plugin-transform-react-remove-prop-types@npm:0.4.24" checksum: 54afe56d67f0d118c9da23996f39948e502a152b3f582eb6e8f163fcb76c2c1ea4e0cdd4f9fac5c0ef050eab4fe0a950b0b74aae6237bcc0d31d8fc4cc808d1a languageName: node linkType: hard -"babel-preset-jest@npm:^24.9.0": - version: 24.9.0 - resolution: "babel-preset-jest@npm:24.9.0" +"babel-preset-current-node-syntax@npm:^1.0.0": + version: 1.0.1 + resolution: "babel-preset-current-node-syntax@npm:1.0.1" + dependencies: + "@babel/plugin-syntax-async-generators": ^7.8.4 + "@babel/plugin-syntax-bigint": ^7.8.3 + "@babel/plugin-syntax-class-properties": ^7.8.3 + "@babel/plugin-syntax-import-meta": ^7.8.3 + "@babel/plugin-syntax-json-strings": ^7.8.3 + "@babel/plugin-syntax-logical-assignment-operators": ^7.8.3 + "@babel/plugin-syntax-nullish-coalescing-operator": ^7.8.3 + "@babel/plugin-syntax-numeric-separator": ^7.8.3 + "@babel/plugin-syntax-object-rest-spread": ^7.8.3 + "@babel/plugin-syntax-optional-catch-binding": ^7.8.3 + "@babel/plugin-syntax-optional-chaining": ^7.8.3 + "@babel/plugin-syntax-top-level-await": ^7.8.3 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: d118c2742498c5492c095bc8541f4076b253e705b5f1ad9a2e7d302d81a84866f0070346662355c8e25fc02caa28dc2da8d69bcd67794a0d60c4d6fab6913cc8 + languageName: node + linkType: hard + +"babel-preset-jest@npm:^26.6.2": + version: 26.6.2 + resolution: "babel-preset-jest@npm:26.6.2" dependencies: - "@babel/plugin-syntax-object-rest-spread": ^7.0.0 - babel-plugin-jest-hoist: ^24.9.0 + babel-plugin-jest-hoist: ^26.6.2 + babel-preset-current-node-syntax: ^1.0.0 peerDependencies: "@babel/core": ^7.0.0 - checksum: d32ab6255e36ed06ef1cc53089b261a74c171d17758792979c2992d4fcb97982f67f837156bbef38042eb11751496a783dee61aafcbf2d7449ed94d52483bee2 + checksum: 1d9bef3a7ac6751a09d29ceb84be8b1998abd210fafa12223689c744db4f2a63ab90cba7986a71f3154d9aceda9dbeca563178731d21cbaf793b4096ed3a4d01 languageName: node linkType: hard -"babel-preset-react-app@npm:^9.1.2": - version: 9.1.2 - resolution: "babel-preset-react-app@npm:9.1.2" +"babel-preset-react-app@npm:^10.0.0": + version: 10.0.1 + resolution: "babel-preset-react-app@npm:10.0.1" dependencies: - "@babel/core": 7.9.0 - "@babel/plugin-proposal-class-properties": 7.8.3 - "@babel/plugin-proposal-decorators": 7.8.3 - "@babel/plugin-proposal-nullish-coalescing-operator": 7.8.3 - "@babel/plugin-proposal-numeric-separator": 7.8.3 - "@babel/plugin-proposal-optional-chaining": 7.9.0 - "@babel/plugin-transform-flow-strip-types": 7.9.0 - "@babel/plugin-transform-react-display-name": 7.8.3 - "@babel/plugin-transform-runtime": 7.9.0 - "@babel/preset-env": 7.9.0 - "@babel/preset-react": 7.9.1 - "@babel/preset-typescript": 7.9.0 - "@babel/runtime": 7.9.0 - babel-plugin-macros: 2.8.0 - babel-plugin-transform-react-remove-prop-types: 0.4.24 - checksum: ebdf90c922394ba3c72a326e14c5deff45292fdb46e114d5d83e9a1cf9cb433262254def4347767f5c7aa0924f0795dadae5c82bbc3acd77111c0b1df9316cd9 + "@babel/core": ^7.16.0 + "@babel/plugin-proposal-class-properties": ^7.16.0 + "@babel/plugin-proposal-decorators": ^7.16.4 + "@babel/plugin-proposal-nullish-coalescing-operator": ^7.16.0 + "@babel/plugin-proposal-numeric-separator": ^7.16.0 + "@babel/plugin-proposal-optional-chaining": ^7.16.0 + "@babel/plugin-proposal-private-methods": ^7.16.0 + "@babel/plugin-transform-flow-strip-types": ^7.16.0 + "@babel/plugin-transform-react-display-name": ^7.16.0 + "@babel/plugin-transform-runtime": ^7.16.4 + "@babel/preset-env": ^7.16.4 + "@babel/preset-react": ^7.16.0 + "@babel/preset-typescript": ^7.16.0 + "@babel/runtime": ^7.16.3 + babel-plugin-macros: ^3.1.0 + babel-plugin-transform-react-remove-prop-types: ^0.4.24 + checksum: ee66043484e67b8aef2541976388299691478ea00834f3bb14b6b3d5edcd316a5ac95351f6ec084b41ee555cad820d4194280ad38ce51884fedc7e8946a57b74 languageName: node linkType: hard @@ -4733,6 +5211,19 @@ __metadata: languageName: node linkType: hard +"bfj@npm:^7.0.2": + version: 7.1.0 + resolution: "bfj@npm:7.1.0" + dependencies: + bluebird: ^3.7.2 + check-types: ^11.2.3 + hoopy: ^0.1.4 + jsonpath: ^1.1.1 + tryer: ^1.0.1 + checksum: 36da9ed36c60f377a3f43bb0433092af7dc40442914b8155a1330ae86b1905640baf57e9c195ab83b36d6518b27cf8ed880adff663aa444c193be149e027d722 + languageName: node + linkType: hard + "big.js@npm:^5.2.2": version: 5.2.2 resolution: "big.js@npm:5.2.2" @@ -4915,15 +5406,6 @@ __metadata: languageName: node linkType: hard -"browser-resolve@npm:^1.11.3": - version: 1.11.3 - resolution: "browser-resolve@npm:1.11.3" - dependencies: - resolve: 1.1.7 - checksum: 431bfc1a17406362a3010a2c35503eb7d1253dbcb8081c1ce236ddb0b954a33d52dcaf0b07f64c0f20394d6eeec1be4f6551da3734ce9ed5dcc38e876c96d5d5 - languageName: node - linkType: hard - "browserify-aes@npm:^1.0.0, browserify-aes@npm:^1.0.4, browserify-aes@npm:^1.2.0": version: 1.2.0 resolution: "browserify-aes@npm:1.2.0" @@ -4998,21 +5480,21 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:4.10.0": - version: 4.10.0 - resolution: "browserslist@npm:4.10.0" +"browserslist@npm:4.14.2": + version: 4.14.2 + resolution: "browserslist@npm:4.14.2" dependencies: - caniuse-lite: ^1.0.30001035 - electron-to-chromium: ^1.3.378 - node-releases: ^1.1.52 - pkg-up: ^3.1.0 + caniuse-lite: ^1.0.30001125 + electron-to-chromium: ^1.3.564 + escalade: ^3.0.2 + node-releases: ^1.1.61 bin: browserslist: cli.js - checksum: 35fdd9653656008a4f7a42026faa3e5ff3c5da83a39b7163675ae96985cbf8607beba55a877f2cf68f34cba7c8bb95418683664b663a051f094eb6d73dd4baf5 + checksum: 44b5d7a444b867e1f027923f37a8ed537b4403f8a85a35869904e7d3e4071b37459df08d41ab4d425f5191f3125f1c5a191cbff9070f81f4d311803dc0a2fb0f languageName: node linkType: hard -"browserslist@npm:^4.0.0, browserslist@npm:^4.12.0, browserslist@npm:^4.16.6, browserslist@npm:^4.6.2, browserslist@npm:^4.6.4, browserslist@npm:^4.9.1": +"browserslist@npm:^4.0.0, browserslist@npm:^4.12.0, browserslist@npm:^4.16.6, browserslist@npm:^4.6.2, browserslist@npm:^4.6.4": version: 4.22.1 resolution: "browserslist@npm:4.22.1" dependencies: @@ -5026,7 +5508,7 @@ __metadata: languageName: node linkType: hard -"browserslist@npm:^4.22.2": +"browserslist@npm:^4.22.2, browserslist@npm:^4.23.0": version: 4.23.0 resolution: "browserslist@npm:4.23.0" dependencies: @@ -5105,6 +5587,13 @@ __metadata: languageName: node linkType: hard +"builtin-modules@npm:^3.1.0": + version: 3.3.0 + resolution: "builtin-modules@npm:3.3.0" + checksum: db021755d7ed8be048f25668fe2117620861ef6703ea2c65ed2779c9e3636d5c3b82325bd912244293959ff3ae303afa3471f6a15bf5060c103e4cc3a839749d + languageName: node + linkType: hard + "builtin-status-codes@npm:^3.0.0": version: 3.0.0 resolution: "builtin-status-codes@npm:3.0.0" @@ -5149,33 +5638,7 @@ __metadata: languageName: node linkType: hard -"cacache@npm:^13.0.1": - version: 13.0.1 - resolution: "cacache@npm:13.0.1" - dependencies: - chownr: ^1.1.2 - figgy-pudding: ^3.5.1 - fs-minipass: ^2.0.0 - glob: ^7.1.4 - graceful-fs: ^4.2.2 - infer-owner: ^1.0.4 - lru-cache: ^5.1.1 - minipass: ^3.0.0 - minipass-collect: ^1.0.2 - minipass-flush: ^1.0.5 - minipass-pipeline: ^1.2.2 - mkdirp: ^0.5.1 - move-concurrently: ^1.0.1 - p-map: ^3.0.0 - promise-inflight: ^1.0.1 - rimraf: ^2.7.1 - ssri: ^7.0.0 - unique-filename: ^1.1.1 - checksum: 733e65de5a0db3f1c181aa780f60ff121b5efd9b7c0851e1e1f213df768a790882d4d5af987fb0cfa70c5c6c4834e0474a291ac8872d227056f7ea12c1447092 - languageName: node - linkType: hard - -"cacache@npm:^15.2.0, cacache@npm:^15.3.0": +"cacache@npm:^15.0.5, cacache@npm:^15.2.0, cacache@npm:^15.3.0": version: 15.3.0 resolution: "cacache@npm:15.3.0" dependencies: @@ -5261,10 +5724,16 @@ __metadata: languageName: node linkType: hard -"call-me-maybe@npm:^1.0.1": - version: 1.0.1 - resolution: "call-me-maybe@npm:1.0.1" - checksum: d19e9d6ac2c6a83fb1215718b64c5e233f688ebebb603bdfe4af59cde952df1f2b648530fab555bf290ea910d69d7d9665ebc916e871e0e194f47c2e48e4886b +"call-bind@npm:^1.0.5, call-bind@npm:^1.0.6, call-bind@npm:^1.0.7": + version: 1.0.7 + resolution: "call-bind@npm:1.0.7" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + set-function-length: ^1.2.1 + checksum: 295c0c62b90dd6522e6db3b0ab1ce26bdf9e7404215bda13cfee25b626b5ff1a7761324d58d38b1ef1607fc65aca2d06e44d2e18d0dfc6c14b465b00d8660029 languageName: node linkType: hard @@ -5310,16 +5779,6 @@ __metadata: languageName: node linkType: hard -"camelcase-keys@npm:^2.0.0": - version: 2.1.0 - resolution: "camelcase-keys@npm:2.1.0" - dependencies: - camelcase: ^2.0.0 - map-obj: ^1.0.0 - checksum: 97d2993da5db44d45e285910c70a54ce7f83a2be05afceaafd9831f7aeaf38a48dcdede5ca3aae2b2694852281d38dc459706e346942c5df0bf755f4133f5c39 - languageName: node - linkType: hard - "camelcase-keys@npm:^6.2.2": version: 6.2.2 resolution: "camelcase-keys@npm:6.2.2" @@ -5338,17 +5797,10 @@ __metadata: languageName: node linkType: hard -"camelcase@npm:^2.0.0": - version: 2.1.1 - resolution: "camelcase@npm:2.1.1" - checksum: 20a3ef08f348de832631d605362ffe447d883ada89617144a82649363ed5860923b021f8e09681624ef774afb93ff3597cfbcf8aaf0574f65af7648f1aea5e50 - languageName: node - linkType: hard - -"camelcase@npm:^3.0.0": - version: 3.0.0 - resolution: "camelcase@npm:3.0.0" - checksum: ae4fe1c17c8442a3a345a6b7d2393f028ab7a7601af0c352ad15d1ab97ca75112e19e29c942b2a214898e160194829b68923bce30e018d62149c6d84187f1673 +"camelcase@npm:^6.0.0, camelcase@npm:^6.1.0, camelcase@npm:^6.2.0": + version: 6.3.0 + resolution: "camelcase@npm:6.3.0" + checksum: 8c96818a9076434998511251dcb2761a94817ea17dbdc37f47ac080bd088fc62c7369429a19e2178b993497132c8cbcf5cc1f44ba963e76782ba469c0474938d languageName: node linkType: hard @@ -5371,10 +5823,24 @@ __metadata: languageName: node linkType: hard -"caniuse-lite@npm:1.0.30001606, caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001035, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001541, caniuse-lite@npm:^1.0.30001587": - version: 1.0.30001606 - resolution: "caniuse-lite@npm:1.0.30001606" - checksum: fcf2d799d8cb159f4f5b44cd9d2171b18df4bcfdf2770cc8a79c4bb0bc5fd19ed089854223865ced32eacffb60a0a9257c8a1d0ef239e9dc3909f587727e9bb5 +"caniuse-lite@npm:1.0.30001612": + version: 1.0.30001612 + resolution: "caniuse-lite@npm:1.0.30001612" + checksum: 2b6ab6a19c72bdf8dccac824944e828a2a1fae52c6dfeb2d64ccecfd60d0466d2e5a392e996da2150d92850188a5034666dceed34a38d978177f6934e0bf106d + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30000981, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001541, caniuse-lite@npm:^1.0.30001587": + version: 1.0.30001614 + resolution: "caniuse-lite@npm:1.0.30001614" + checksum: 1b695625f9a1b08584c3c229d4b8deaebb89e7901a2a2ffe599a6250c0a79fc61afc49c374c32a76dbf593a5dedac3229bb0140bbacd438276211bdd1d7c4958 + languageName: node + linkType: hard + +"caniuse-lite@npm:^1.0.30001125": + version: 1.0.30001610 + resolution: "caniuse-lite@npm:1.0.30001610" + checksum: 580c7367aafd7e524f4e3f0e8b22ac08d081a4d44ceece211f1758e214df9a87961750fb1e1ee28a2cd2830f0daf3edafe5e1d87bf1eefbbe7c6cf3d00e2979d languageName: node linkType: hard @@ -5401,7 +5867,7 @@ __metadata: languageName: node linkType: hard -"chalk@npm:2.4.2, chalk@npm:^2.0.0, chalk@npm:^2.0.1, chalk@npm:^2.1.0, chalk@npm:^2.3.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2": +"chalk@npm:2.4.2, chalk@npm:^2.0.0, chalk@npm:^2.3.0, chalk@npm:^2.4.1, chalk@npm:^2.4.2": version: 2.4.2 resolution: "chalk@npm:2.4.2" dependencies: @@ -5412,19 +5878,6 @@ __metadata: languageName: node linkType: hard -"chalk@npm:^1.1.3": - version: 1.1.3 - resolution: "chalk@npm:1.1.3" - dependencies: - ansi-styles: ^2.2.1 - escape-string-regexp: ^1.0.2 - has-ansi: ^2.0.0 - strip-ansi: ^3.0.0 - supports-color: ^2.0.0 - checksum: 9d2ea6b98fc2b7878829eec223abcf404622db6c48396a9b9257f6d0ead2acf18231ae368d6a664a83f272b0679158da12e97b5229f794939e555cc574478acd - languageName: node - linkType: hard - "chalk@npm:^4.0.0, chalk@npm:^4.1.0, chalk@npm:^4.1.2": version: 4.1.2 resolution: "chalk@npm:4.1.2" @@ -5442,10 +5895,10 @@ __metadata: languageName: node linkType: hard -"chardet@npm:^0.7.0": - version: 0.7.0 - resolution: "chardet@npm:0.7.0" - checksum: 6fd5da1f5d18ff5712c1e0aed41da200d7c51c28f11b36ee3c7b483f3696dabc08927fc6b227735eb8f0e1215c9a8abd8154637f3eff8cada5959df7f58b024d +"char-regex@npm:^1.0.2": + version: 1.0.2 + resolution: "char-regex@npm:1.0.2" + checksum: b563e4b6039b15213114626621e7a3d12f31008bdce20f9c741d69987f62aeaace7ec30f6018890ad77b2e9b4d95324c9f5acfca58a9441e3b1dcdd1e2525d17 languageName: node linkType: hard @@ -5456,6 +5909,13 @@ __metadata: languageName: node linkType: hard +"check-types@npm:^11.2.3": + version: 11.2.3 + resolution: "check-types@npm:11.2.3" + checksum: f99ff09ae65e63cfcfa40a1275c0a70d8c43ffbf9ac35095f3bf030cc70361c92e075a9975a1144329e50b4fe4620be6bedb4568c18abc96071a3e23aed3ed8e + languageName: node + linkType: hard + "cheerio-select@npm:^1.5.0": version: 1.5.0 resolution: "cheerio-select@npm:1.5.0" @@ -5507,7 +5967,7 @@ __metadata: languageName: node linkType: hard -"chokidar@npm:^3.3.0, chokidar@npm:^3.4.0, chokidar@npm:^3.4.1": +"chokidar@npm:^3.4.1": version: 3.5.3 resolution: "chokidar@npm:3.5.3" dependencies: @@ -5526,7 +5986,7 @@ __metadata: languageName: node linkType: hard -"chownr@npm:^1.1.1, chownr@npm:^1.1.2": +"chownr@npm:^1.1.1": version: 1.1.4 resolution: "chownr@npm:1.1.4" checksum: 115648f8eb38bac5e41c3857f3e663f9c39ed6480d1349977c4d96c95a47266fcacc5a5aabf3cb6c481e22d72f41992827db47301851766c4fd77ac21a4f081d @@ -5571,6 +6031,13 @@ __metadata: languageName: node linkType: hard +"cjs-module-lexer@npm:^0.6.0": + version: 0.6.0 + resolution: "cjs-module-lexer@npm:0.6.0" + checksum: 445b039607efd74561d7db8d0867031c8b6a69f25e83fdd861b0fa1fbc11f12de057ba1db80637f3c9016774354092af5325eebb90505d65ccc5389cae09d1fd + languageName: node + linkType: hard + "class-autobind@npm:^0.1.4": version: 0.1.4 resolution: "class-autobind@npm:0.1.4" @@ -5652,31 +6119,6 @@ __metadata: languageName: node linkType: hard -"cli-width@npm:^2.0.0": - version: 2.2.1 - resolution: "cli-width@npm:2.2.1" - checksum: 3c21b897a2ff551ae5b3c3ab32c866ed2965dcf7fb442f81adf0e27f4a397925c8f84619af7bcc6354821303f6ee9b2aa31d248306174f32c287986158cf4eed - languageName: node - linkType: hard - -"cli-width@npm:^3.0.0": - version: 3.0.0 - resolution: "cli-width@npm:3.0.0" - checksum: 4c94af3769367a70e11ed69aa6095f1c600c0ff510f3921ab4045af961820d57c0233acfa8b6396037391f31b4c397e1f614d234294f979ff61430a6c166c3f6 - languageName: node - linkType: hard - -"cliui@npm:^3.2.0": - version: 3.2.0 - resolution: "cliui@npm:3.2.0" - dependencies: - string-width: ^1.0.1 - strip-ansi: ^3.0.1 - wrap-ansi: ^2.0.0 - checksum: c68d1dbc3e347bfe79ed19cc7f48007d5edd6cd8438342e32073e0b4e311e3c44e1f4f19221462bc6590de56c2df520e427533a9dde95dee25710bec322746ad - languageName: node - linkType: hard - "cliui@npm:^5.0.0": version: 5.0.0 resolution: "cliui@npm:5.0.0" @@ -5688,6 +6130,17 @@ __metadata: languageName: node linkType: hard +"cliui@npm:^6.0.0": + version: 6.0.0 + resolution: "cliui@npm:6.0.0" + dependencies: + string-width: ^4.2.0 + strip-ansi: ^6.0.0 + wrap-ansi: ^6.2.0 + checksum: 4fcfd26d292c9f00238117f39fc797608292ae36bac2168cfee4c85923817d0607fe21b3329a8621e01aedf512c99b7eaa60e363a671ffd378df6649fb48ae42 + languageName: node + linkType: hard + "cliui@npm:^7.0.2": version: 7.0.4 resolution: "cliui@npm:7.0.4" @@ -5710,19 +6163,6 @@ __metadata: languageName: node linkType: hard -"clone-deep@npm:^0.2.4": - version: 0.2.4 - resolution: "clone-deep@npm:0.2.4" - dependencies: - for-own: ^0.1.3 - is-plain-object: ^2.0.1 - kind-of: ^3.0.2 - lazy-cache: ^1.0.3 - shallow-clone: ^0.1.2 - checksum: bcf9752052130c270c47d3e1c357497354b91d682f507e0079bec5950975b3293b619d9e100d70874606d716f2376e84956b045759a09af703e1038ecad6c438 - languageName: node - linkType: hard - "clone-deep@npm:^4.0.1": version: 4.0.1 resolution: "clone-deep@npm:4.0.1" @@ -5759,10 +6199,10 @@ __metadata: languageName: node linkType: hard -"code-point-at@npm:^1.0.0": - version: 1.1.0 - resolution: "code-point-at@npm:1.1.0" - checksum: 17d5666611f9b16d64fdf48176d9b7fb1c7d1c1607a189f7e600040a11a6616982876af148230336adb7d8fe728a559f743a4e29db3747e3b1a32fa7f4529681 +"collect-v8-coverage@npm:^1.0.0": + version: 1.0.2 + resolution: "collect-v8-coverage@npm:1.0.2" + checksum: c10f41c39ab84629d16f9f6137bc8a63d332244383fc368caf2d2052b5e04c20cd1fd70f66fcf4e2422b84c8226598b776d39d5f2d2a51867cc1ed5d1982b4da languageName: node linkType: hard @@ -5818,7 +6258,7 @@ __metadata: languageName: node linkType: hard -"color-support@npm:^1.1.2, color-support@npm:^1.1.3": +"color-support@npm:^1.1.3": version: 1.1.3 resolution: "color-support@npm:1.1.3" bin: @@ -5851,7 +6291,7 @@ __metadata: languageName: node linkType: hard -"combined-stream@npm:^1.0.6, combined-stream@npm:~1.0.6": +"combined-stream@npm:^1.0.6, combined-stream@npm:^1.0.8, combined-stream@npm:~1.0.6": version: 1.0.8 resolution: "combined-stream@npm:1.0.8" dependencies: @@ -5860,7 +6300,7 @@ __metadata: languageName: node linkType: hard -"commander@npm:^2.11.0, commander@npm:^2.12.1, commander@npm:^2.19.0, commander@npm:^2.20.0": +"commander@npm:^2.12.1, commander@npm:^2.19.0, commander@npm:^2.20.0": version: 2.20.3 resolution: "commander@npm:2.20.3" checksum: ab8c07884e42c3a8dbc5dd9592c606176c7eb5c1ca5ff274bcf907039b2c41de3626f684ea75ccf4d361ba004bbaff1f577d5384c155f3871e456bdf27becf9e @@ -5954,10 +6394,10 @@ __metadata: languageName: node linkType: hard -"confusing-browser-globals@npm:^1.0.9": - version: 1.0.10 - resolution: "confusing-browser-globals@npm:1.0.10" - checksum: 7ccdc44c2ca419cf6576c3e4336106e18d1c5337f547e461342f51aec4a10f96fdfe45414b522be3c7d24ea0b62bf4372cd37768022e4d6161707ffb2c0987e6 +"confusing-browser-globals@npm:^1.0.10": + version: 1.0.11 + resolution: "confusing-browser-globals@npm:1.0.11" + checksum: 3afc635abd37e566477f610e7978b15753f0e84025c25d49236f1f14d480117185516bdd40d2a2167e6bed8048641a9854964b9c067e3dcdfa6b5d0ad3c3a5ef languageName: node linkType: hard @@ -5975,7 +6415,7 @@ __metadata: languageName: node linkType: hard -"console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0": +"console-control-strings@npm:^1.1.0": version: 1.1.0 resolution: "console-control-strings@npm:1.1.0" checksum: 8755d76787f94e6cf79ce4666f0c5519906d7f5b02d4b884cf41e11dcd759ed69c57da0670afd9236d229a46e0f9cf519db0cd829c6dca820bb5a5c3def584ed @@ -5989,13 +6429,6 @@ __metadata: languageName: node linkType: hard -"contains-path@npm:^0.1.0": - version: 0.1.0 - resolution: "contains-path@npm:0.1.0" - checksum: 94ecfd944e0bc51be8d3fc596dcd17d705bd4c8a1a627952a3a8c5924bac01c7ea19034cf40b4b4f89e576cdead130a7e5fd38f5f7f07ef67b4b261d875871e3 - languageName: node - linkType: hard - "content-disposition@npm:0.5.4": version: 0.5.4 resolution: "content-disposition@npm:0.5.4" @@ -6044,6 +6477,13 @@ __metadata: languageName: node linkType: hard +"convert-source-map@npm:^1.6.0": + version: 1.9.0 + resolution: "convert-source-map@npm:1.9.0" + checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8 + languageName: node + linkType: hard + "convert-source-map@npm:^2.0.0": version: 2.0.0 resolution: "convert-source-map@npm:2.0.0" @@ -6095,20 +6535,12 @@ __metadata: languageName: node linkType: hard -"core-js-compat@npm:^3.14.0, core-js-compat@npm:^3.15.0, core-js-compat@npm:^3.6.2": - version: 3.15.1 - resolution: "core-js-compat@npm:3.15.1" +"core-js-compat@npm:^3.31.0, core-js-compat@npm:^3.36.1": + version: 3.36.1 + resolution: "core-js-compat@npm:3.36.1" dependencies: - browserslist: ^4.16.6 - semver: 7.0.0 - checksum: cf2fb3406c7fd82edee3ccf9e55e538cf75da79845d5dbffaf979cb9e73e26943ee6e7d07c5cbc50c5909fba1c5a4ca499d0f249fdb491da45b40f8584a4c761 - languageName: node - linkType: hard - -"core-js-pure@npm:^3.15.0": - version: 3.15.1 - resolution: "core-js-pure@npm:3.15.1" - checksum: e4053f6f3ab4268f991d76f4c3f918cfa5a95182d0c5ddcc32d381bc208318b5817db8fb01d531363a7d110b46ea1c6ffb14e832f661bfea3e213d52d9b92658 + browserslist: ^4.23.0 + checksum: c9109bd599a97b5d20f25fc8b8339b8c7f3fca5f9a1bebd397805383ff7699e117786c7ffe0f7a95058a6fa5e0e1435d4c10e5cda6ad86ce1957986bb6580562 languageName: node linkType: hard @@ -6126,13 +6558,20 @@ __metadata: languageName: node linkType: hard -"core-js@npm:^3.5.0, core-js@npm:^3.6.4": +"core-js@npm:^3.6.4": version: 3.15.1 resolution: "core-js@npm:3.15.1" checksum: d44c1099b4028bee17990473df0b508ad0f6701aba9e13055183fe4a8bd1459e9e22f22b8e6c0b0a6ac0974b404672df47d52be3341a776a227fc368f2aa1fbe languageName: node linkType: hard +"core-js@npm:^3.6.5": + version: 3.36.1 + resolution: "core-js@npm:3.36.1" + checksum: 6f6c152179bd0673da34e67a82c6a5c37f31f9fbe908e9caf93749dc62a25b6e07fbff2411de3b74bb2d0661b7f9fb247115ba8efabf9904f5fef26edead515e + languageName: node + linkType: hard + "core-util-is@npm:1.0.2, core-util-is@npm:~1.0.0": version: 1.0.2 resolution: "core-util-is@npm:1.0.2" @@ -6140,7 +6579,7 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^5.0.0, cosmiconfig@npm:^5.2.1": +"cosmiconfig@npm:^5.0.0": version: 5.2.1 resolution: "cosmiconfig@npm:5.2.1" dependencies: @@ -6152,16 +6591,16 @@ __metadata: languageName: node linkType: hard -"cosmiconfig@npm:^6.0.0": - version: 6.0.0 - resolution: "cosmiconfig@npm:6.0.0" +"cosmiconfig@npm:^7.0.0": + version: 7.1.0 + resolution: "cosmiconfig@npm:7.1.0" dependencies: "@types/parse-json": ^4.0.0 - import-fresh: ^3.1.0 + import-fresh: ^3.2.1 parse-json: ^5.0.0 path-type: ^4.0.0 - yaml: ^1.7.2 - checksum: 8eed7c854b91643ecb820767d0deb038b50780ecc3d53b0b19e03ed8aabed4ae77271198d1ae3d49c3b110867edf679f5faad924820a8d1774144a87cb6f98fc + yaml: ^1.10.0 + checksum: c53bf7befc1591b2651a22414a5e786cd5f2eeaa87f3678a3d49d6069835a9d8d1aef223728e98aa8fec9a95bf831120d245096db12abe019fecb51f5696c96f languageName: node linkType: hard @@ -6211,18 +6650,18 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:7.0.1": - version: 7.0.1 - resolution: "cross-spawn@npm:7.0.1" +"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" dependencies: path-key: ^3.1.0 shebang-command: ^2.0.0 which: ^2.0.1 - checksum: 5c1c52be2d24f0ada793920bf0beca61ea9cc03bb5c400617ddfd2c03f10ed86a0c39fb67bcf2cee91ec4dd7e9f1595ed9c40f84352d2881937bf861281f651a + checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 languageName: node linkType: hard -"cross-spawn@npm:^6.0.0, cross-spawn@npm:^6.0.5": +"cross-spawn@npm:^6.0.0": version: 6.0.5 resolution: "cross-spawn@npm:6.0.5" dependencies: @@ -6235,17 +6674,6 @@ __metadata: languageName: node linkType: hard -"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": - version: 7.0.3 - resolution: "cross-spawn@npm:7.0.3" - dependencies: - path-key: ^3.1.0 - shebang-command: ^2.0.0 - which: ^2.0.1 - checksum: 671cc7c7288c3a8406f3c69a3ae2fc85555c04169e9d611def9a675635472614f1c0ed0ef80955d5b6d4e724f6ced67f0ad1bb006c2ea643488fcfef994d7f52 - languageName: node - linkType: hard - "crypto-browserify@npm:^3.11.0": version: 3.12.0 resolution: "crypto-browserify@npm:3.12.0" @@ -6265,6 +6693,13 @@ __metadata: languageName: node linkType: hard +"crypto-random-string@npm:^1.0.0": + version: 1.0.0 + resolution: "crypto-random-string@npm:1.0.0" + checksum: 6fc61a46c18547b49a93da24f4559c4a1c859f4ee730ecc9533c1ba89fa2a9e9d81f390c2789467afbbd0d1c55a6e96a71e4716b6cd3e77736ed5fced7a2df9a + languageName: node + linkType: hard + "css-blank-pseudo@npm:^0.1.4": version: 0.1.4 resolution: "css-blank-pseudo@npm:0.1.4" @@ -6312,25 +6747,25 @@ __metadata: languageName: node linkType: hard -"css-loader@npm:3.4.2": - version: 3.4.2 - resolution: "css-loader@npm:3.4.2" +"css-loader@npm:4.3.0": + version: 4.3.0 + resolution: "css-loader@npm:4.3.0" dependencies: - camelcase: ^5.3.1 + camelcase: ^6.0.0 cssesc: ^3.0.0 icss-utils: ^4.1.1 - loader-utils: ^1.2.3 - normalize-path: ^3.0.0 - postcss: ^7.0.23 + loader-utils: ^2.0.0 + postcss: ^7.0.32 postcss-modules-extract-imports: ^2.0.0 - postcss-modules-local-by-default: ^3.0.2 - postcss-modules-scope: ^2.1.1 + postcss-modules-local-by-default: ^3.0.3 + postcss-modules-scope: ^2.2.0 postcss-modules-values: ^3.0.0 - postcss-value-parser: ^4.0.2 - schema-utils: ^2.6.0 + postcss-value-parser: ^4.1.0 + schema-utils: ^2.7.1 + semver: ^7.3.2 peerDependencies: - webpack: ^4.0.0 || ^5.0.0 - checksum: dbd80f052b41ea7c33d96a2fbeabca82773f7e3567300c636ffb079ffcf8ba111b02f315346942334ed27ffc137323c9a4ac1e446eaed5837abbdd3fdd371a0c + webpack: ^4.27.0 || ^5.0.0 + checksum: 697a8838f0975f86c634e7a920572604879a9738128fcc01e5393fae5ac9a7a1a925c0d14ebb6ed67fa7e14bd17849eec152a99e3299cc92f422f6b0cd4eff73 languageName: node linkType: hard @@ -6557,19 +6992,26 @@ __metadata: languageName: node linkType: hard -"cssom@npm:0.3.x, cssom@npm:>= 0.3.2 < 0.4.0, cssom@npm:^0.3.4": +"cssom@npm:^0.4.4": + version: 0.4.4 + resolution: "cssom@npm:0.4.4" + checksum: e3bc1076e7ee4213d4fef05e7ae03bfa83dc05f32611d8edc341f4ecc3d9647b89c8245474c7dd2cdcdb797a27c462e99da7ad00a34399694559f763478ff53f + languageName: node + linkType: hard + +"cssom@npm:~0.3.6": version: 0.3.8 resolution: "cssom@npm:0.3.8" checksum: 24beb3087c76c0d52dd458be9ee1fbc80ac771478a9baef35dd258cdeb527c68eb43204dd439692bb2b1ae5272fa5f2946d10946edab0d04f1078f85e06bc7f6 languageName: node linkType: hard -"cssstyle@npm:^1.0.0, cssstyle@npm:^1.1.1": - version: 1.4.0 - resolution: "cssstyle@npm:1.4.0" +"cssstyle@npm:^2.3.0": + version: 2.3.0 + resolution: "cssstyle@npm:2.3.0" dependencies: - cssom: 0.3.x - checksum: 7efb9731d68dd042f32e0e3bbc7c1096653ba521f21ab1c5b158862321e4fcbfb51070641b834fadc8dd070a634dd43f328177e00d1b8481b5143a3e09f3d3f6 + cssom: ~0.3.6 + checksum: 5f05e6fd2e3df0b44695c2f08b9ef38b011862b274e320665176467c0725e44a53e341bc4959a41176e83b66064ab786262e7380fd1cabeae6efee0d255bb4e3 languageName: node linkType: hard @@ -6594,15 +7036,6 @@ __metadata: languageName: node linkType: hard -"currently-unhandled@npm:^0.4.1": - version: 0.4.1 - resolution: "currently-unhandled@npm:0.4.1" - dependencies: - array-find-index: ^1.0.1 - checksum: 1f59fe10b5339b54b1a1eee110022f663f3495cf7cf2f480686e89edc7fa8bfe42dbab4b54f85034bc8b092a76cc7becbc2dad4f9adad332ab5831bec39ad540 - languageName: node - linkType: hard - "cwlts@npm:1.15.29": version: 1.15.29 resolution: "cwlts@npm:1.15.29" @@ -6699,10 +7132,10 @@ __metadata: languageName: node linkType: hard -"damerau-levenshtein@npm:^1.0.4": - version: 1.0.7 - resolution: "damerau-levenshtein@npm:1.0.7" - checksum: ec8161cb381523e0db9b5c9b64863736da3197808b6fdc4a3a2ca764c0b4357e9232a4c5592220fb18755a91240b8fee7b13ab1b269fbbdc5f68c36f0053aceb +"damerau-levenshtein@npm:^1.0.8": + version: 1.0.8 + resolution: "damerau-levenshtein@npm:1.0.8" + checksum: d240b7757544460ae0586a341a53110ab0a61126570ef2d8c731e3eab3f0cb6e488e2609e6a69b46727635de49be20b071688698744417ff1b6c1d7ccd03e0de languageName: node linkType: hard @@ -6715,14 +7148,47 @@ __metadata: languageName: node linkType: hard -"data-urls@npm:^1.0.0, data-urls@npm:^1.1.0": - version: 1.1.0 - resolution: "data-urls@npm:1.1.0" +"data-urls@npm:^2.0.0": + version: 2.0.0 + resolution: "data-urls@npm:2.0.0" + dependencies: + abab: ^2.0.3 + whatwg-mimetype: ^2.3.0 + whatwg-url: ^8.0.0 + checksum: 97caf828aac25e25e04ba6869db0f99c75e6859bb5b424ada28d3e7841941ebf08ddff3c1b1bb4585986bd507a5d54c2a716853ea6cb98af877400e637393e71 + languageName: node + linkType: hard + +"data-view-buffer@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-buffer@npm:1.0.1" + dependencies: + call-bind: ^1.0.6 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: ce24348f3c6231223b216da92e7e6a57a12b4af81a23f27eff8feabdf06acfb16c00639c8b705ca4d167f761cfc756e27e5f065d0a1f840c10b907fdaf8b988c + languageName: node + linkType: hard + +"data-view-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "data-view-byte-length@npm:1.0.1" + dependencies: + call-bind: ^1.0.7 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: dbb3200edcb7c1ef0d68979834f81d64fd8cab2f7691b3a4c6b97e67f22182f3ec2c8602efd7b76997b55af6ff8bce485829c1feda4fa2165a6b71fb7baa4269 + languageName: node + linkType: hard + +"data-view-byte-offset@npm:^1.0.0": + version: 1.0.0 + resolution: "data-view-byte-offset@npm:1.0.0" dependencies: - abab: ^2.0.0 - whatwg-mimetype: ^2.2.0 - whatwg-url: ^7.0.0 - checksum: dc4bd9621df0dff336d7c4c0517c792488ef3cf11cd37e72ab80f3a7f0a0aa14bad677ac97cf22c87c6eb9518e58b98590e1c8c756b56240940f0e470c81612e + call-bind: ^1.0.6 + es-errors: ^1.3.0 + is-data-view: ^1.0.1 + checksum: 7f0bf8720b7414ca719eedf1846aeec392f2054d7af707c5dc9a753cc77eb8625f067fa901e0b5127e831f9da9056138d894b9c2be79c27a21f6db5824f009c2 languageName: node linkType: hard @@ -6754,7 +7220,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0, debug@npm:^2.6.9": +"debug@npm:2.6.9, debug@npm:^2.2.0, debug@npm:^2.3.3, debug@npm:^2.6.0": version: 2.6.9 resolution: "debug@npm:2.6.9" dependencies: @@ -6818,13 +7284,20 @@ __metadata: languageName: node linkType: hard -"decamelize@npm:^1.1.0, decamelize@npm:^1.1.1, decamelize@npm:^1.1.2, decamelize@npm:^1.2.0": +"decamelize@npm:^1.1.0, decamelize@npm:^1.2.0": version: 1.2.0 resolution: "decamelize@npm:1.2.0" checksum: ad8c51a7e7e0720c70ec2eeb1163b66da03e7616d7b98c9ef43cce2416395e84c1e9548dd94f5f6ffecfee9f8b94251fc57121a8b021f2ff2469b2bae247b8aa languageName: node linkType: hard +"decimal.js@npm:^10.2.1": + version: 10.4.3 + resolution: "decimal.js@npm:10.4.3" + checksum: 796404dcfa9d1dbfdc48870229d57f788b48c21c603c3f6554a1c17c10195fc1024de338b0cf9e1efe0c7c167eeb18f04548979bcc5fdfabebb7cc0ae3287bae + languageName: node + linkType: hard + "decode-uri-component@npm:^0.2.0": version: 0.2.2 resolution: "decode-uri-component@npm:0.2.2" @@ -6832,6 +7305,13 @@ __metadata: languageName: node linkType: hard +"dedent@npm:^0.7.0": + version: 0.7.0 + resolution: "dedent@npm:0.7.0" + checksum: 87de191050d9a40dd70cad01159a0bcf05ecb59750951242070b6abf9569088684880d00ba92a955b4058804f16eeaf91d604f283929b4f614d181cd7ae633d2 + languageName: node + linkType: hard + "deep-equal@npm:^1.0.1": version: 1.1.1 resolution: "deep-equal@npm:1.1.1" @@ -6846,6 +7326,13 @@ __metadata: languageName: node linkType: hard +"deep-is@npm:^0.1.3": + version: 0.1.4 + resolution: "deep-is@npm:0.1.4" + checksum: edb65dd0d7d1b9c40b2f50219aef30e116cedd6fc79290e740972c132c09106d2e80aa0bc8826673dd5a00222d4179c84b36a790eef63a4c4bca75a37ef90804 + languageName: node + linkType: hard + "deep-is@npm:~0.1.3": version: 0.1.3 resolution: "deep-is@npm:0.1.3" @@ -6860,6 +7347,13 @@ __metadata: languageName: node linkType: hard +"deepmerge@npm:^4.2.2": + version: 4.3.1 + resolution: "deepmerge@npm:4.3.1" + checksum: 2024c6a980a1b7128084170c4cf56b0fd58a63f2da1660dcfe977415f27b17dbe5888668b59d0b063753f3220719d5e400b7f113609489c90160bb9a5518d052 + languageName: node + linkType: hard + "default-gateway@npm:^4.2.0": version: 4.2.0 resolution: "default-gateway@npm:4.2.0" @@ -6870,6 +7364,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.4": + version: 1.1.4 + resolution: "define-data-property@npm:1.1.4" + dependencies: + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + gopd: ^1.0.1 + checksum: 8068ee6cab694d409ac25936eb861eea704b7763f7f342adbdfe337fc27c78d7ae0eff2364b2917b58c508d723c7a074326d068eef2e45c4edcd85cf94d0313b + languageName: node + linkType: hard + "define-properties@npm:^1.1.2, define-properties@npm:^1.1.3": version: 1.1.3 resolution: "define-properties@npm:1.1.3" @@ -6879,6 +7384,17 @@ __metadata: languageName: node linkType: hard +"define-properties@npm:^1.2.0, define-properties@npm:^1.2.1": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: ^1.0.1 + has-property-descriptors: ^1.0.0 + object-keys: ^1.1.1 + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + "define-property@npm:^0.2.5": version: 0.2.5 resolution: "define-property@npm:0.2.5" @@ -6950,6 +7466,13 @@ __metadata: languageName: node linkType: hard +"dequal@npm:^2.0.3": + version: 2.0.3 + resolution: "dequal@npm:2.0.3" + checksum: 8679b850e1a3d0ebbc46ee780d5df7b478c23f335887464023a631d1b9af051ad4a6595a44220f9ff8ff95a8ddccf019b5ad778a976fd7bbf77383d36f412f90 + languageName: node + linkType: hard + "des.js@npm:^1.0.0": version: 1.0.1 resolution: "des.js@npm:1.0.1" @@ -6967,10 +7490,10 @@ __metadata: languageName: node linkType: hard -"detect-newline@npm:^2.1.0": - version: 2.1.0 - resolution: "detect-newline@npm:2.1.0" - checksum: c55146fd5b97a9ce914f17f85a01466c9e8679289e2d390588b027a58f2e090dbc38457923072369c603b8904f982f87b78fee17e48d5706f35571642f4599f8 +"detect-newline@npm:^3.0.0": + version: 3.1.0 + resolution: "detect-newline@npm:3.1.0" + checksum: ae6cd429c41ad01b164c59ea36f264a2c479598e61cba7c99da24175a7ab80ddf066420f2bec9a1c57a6bead411b4655ff15ad7d281c000a89791f48cbe939e7 languageName: node linkType: hard @@ -6994,13 +7517,6 @@ __metadata: languageName: node linkType: hard -"diff-sequences@npm:^24.9.0": - version: 24.9.0 - resolution: "diff-sequences@npm:24.9.0" - checksum: b81f906ff1737e0a65e8f7ee3ad1d27b426dcc25498731365aeaccc32333da3bf3a7100c963c7104f12c8e64e545114d4fe4c0b90daf2565b0b00b79f0df45c4 - languageName: node - linkType: hard - "diff-sequences@npm:^26.6.2": version: 26.6.2 resolution: "diff-sequences@npm:26.6.2" @@ -7027,19 +7543,9 @@ __metadata: resolution: "diffie-hellman@npm:5.0.3" dependencies: bn.js: ^4.1.0 - miller-rabin: ^4.0.0 - randombytes: ^2.0.0 - checksum: 0e620f322170c41076e70181dd1c24e23b08b47dbb92a22a644f3b89b6d3834b0f8ee19e37916164e5eb1ee26d2aa836d6129f92723995267250a0b541811065 - languageName: node - linkType: hard - -"dir-glob@npm:2.0.0": - version: 2.0.0 - resolution: "dir-glob@npm:2.0.0" - dependencies: - arrify: ^1.0.1 - path-type: ^3.0.0 - checksum: adc4dc5dd9d2cc0a9ce864e52f9ac1c93e34487720fbed68bdf94cef7a9d88be430cc565300750571589dd35e168d0b286120317c0797f83a7cd8e6d9c69fcb7 + miller-rabin: ^4.0.0 + randombytes: ^2.0.0 + checksum: 0e620f322170c41076e70181dd1c24e23b08b47dbb92a22a644f3b89b6d3834b0f8ee19e37916164e5eb1ee26d2aa836d6129f92723995267250a0b541811065 languageName: node linkType: hard @@ -7097,16 +7603,6 @@ __metadata: languageName: node linkType: hard -"doctrine@npm:1.5.0": - version: 1.5.0 - resolution: "doctrine@npm:1.5.0" - dependencies: - esutils: ^2.0.2 - isarray: ^1.0.0 - checksum: 7ce8102a05cbb9d942d49db5461d2f3dd1208ebfed929bf1c04770a1ef6ef540b792e63c45eae4c51f8b16075e0af4a73581a06bad31c37ceb0988f2e398509b - languageName: node - linkType: hard - "doctrine@npm:^2.1.0": version: 2.1.0 resolution: "doctrine@npm:2.1.0" @@ -7185,12 +7681,12 @@ __metadata: languageName: node linkType: hard -"domexception@npm:^1.0.1": - version: 1.0.1 - resolution: "domexception@npm:1.0.1" +"domexception@npm:^2.0.1": + version: 2.0.1 + resolution: "domexception@npm:2.0.1" dependencies: - webidl-conversions: ^4.0.2 - checksum: f564a9c0915dcb83ceefea49df14aaed106b1468fbe505119e8bcb0b77e242534f3aba861978537c0fc9dc6f35b176d0ffc77b3e342820fb27a8f215e7ae4d52 + webidl-conversions: ^5.0.0 + checksum: d638e9cb05c52999f1b2eb87c374b03311ea5b1d69c2f875bc92da73e17db60c12142b45c950228642ff7f845c536b65305483350d080df59003a653da80b691 languageName: node linkType: hard @@ -7406,10 +7902,17 @@ __metadata: languageName: node linkType: hard -"electron-to-chromium@npm:^1.3.378": - version: 1.3.758 - resolution: "electron-to-chromium@npm:1.3.758" - checksum: 2fec13dcdd1b24a2314d309566bd08c7f0ce383787e64ea43c14a7fc2a11c8a76fdb9a56ce7a1da6137e1ef46365f999d10c656f2fb6b9ff792ea3ae808ebb86 +"ejs@npm:^2.6.1": + version: 2.7.4 + resolution: "ejs@npm:2.7.4" + checksum: a1d2bfc7d1f0b39e99ae19b20c9469a25aeddba1ffc225db098110b18d566f73772fcdcc740b108cfda7452276f67d7b64eb359f90285414c942f4ae70713371 + languageName: node + linkType: hard + +"electron-to-chromium@npm:^1.3.564": + version: 1.4.736 + resolution: "electron-to-chromium@npm:1.4.736" + checksum: dcba6d43ffbc40e5d3decb3a0de67b9721a257fefde4eceac0d75202029c62ace7b377d217f49d1ba9cfbad61f89a14514e85a4de77b7205cee336f2e1f0baee languageName: node linkType: hard @@ -7457,7 +7960,14 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^7.0.1, emoji-regex@npm:^7.0.2": +"emittery@npm:^0.7.1": + version: 0.7.2 + resolution: "emittery@npm:0.7.2" + checksum: 908cd933d48a9bcb58ddf39e9a7d4ba1e049de392ccbef010102539a636e03cea2b28218331b7ede41de8165d9ed7f148851c5112ebd2e943117c0f61eff5f10 + languageName: node + linkType: hard + +"emoji-regex@npm:^7.0.1": version: 7.0.3 resolution: "emoji-regex@npm:7.0.3" checksum: 9159b2228b1511f2870ac5920f394c7e041715429a68459ebe531601555f11ea782a8e1718f969df2711d38c66268174407cbca57ce36485544f695c2dfdc96e @@ -7471,10 +7981,10 @@ __metadata: languageName: node linkType: hard -"emojis-list@npm:^2.0.0": - version: 2.1.0 - resolution: "emojis-list@npm:2.1.0" - checksum: fb61fa6356dfcc9fbe6db8e334c29da365a34d3d82a915cb59621883d3023d804fd5edad5acd42b8eec016936e81d3b38e2faf921b32e073758374253afe1272 +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 8487182da74aabd810ac6d6f1994111dfc0e331b01271ae01ec1eb0ad7b5ecc2bbbbd2f053c05cb55a1ac30449527d819bbfbf0e3de1023db308cbcb47f86601 languageName: node linkType: hard @@ -7510,7 +8020,7 @@ __metadata: languageName: node linkType: hard -"enhanced-resolve@npm:^4.1.0": +"enhanced-resolve@npm:^4.3.0": version: 4.5.0 resolution: "enhanced-resolve@npm:4.5.0" dependencies: @@ -7521,7 +8031,7 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.6": +"enquirer@npm:^2.3.5, enquirer@npm:^2.3.6": version: 2.4.1 resolution: "enquirer@npm:2.4.1" dependencies: @@ -7641,7 +8151,7 @@ __metadata: languageName: node linkType: hard -"error-ex@npm:^1.2.0, error-ex@npm:^1.3.1": +"error-ex@npm:^1.3.1": version: 1.3.2 resolution: "error-ex@npm:1.3.2" dependencies: @@ -7650,6 +8160,15 @@ __metadata: languageName: node linkType: hard +"error-stack-parser@npm:^2.0.6": + version: 2.1.4 + resolution: "error-stack-parser@npm:2.1.4" + dependencies: + stackframe: ^1.3.4 + checksum: 3b916d2d14c6682f287c8bfa28e14672f47eafe832701080e420e7cdbaebb2c50293868256a95706ac2330fe078cf5664713158b49bc30d7a5f2ac229ded0e18 + languageName: node + linkType: hard + "es-abstract@npm:^1.17.2, es-abstract@npm:^1.17.4, es-abstract@npm:^1.18.0, es-abstract@npm:^1.18.0-next.1, es-abstract@npm:^1.18.0-next.2, es-abstract@npm:^1.18.2": version: 1.18.3 resolution: "es-abstract@npm:1.18.3" @@ -7674,6 +8193,60 @@ __metadata: languageName: node linkType: hard +"es-abstract@npm:^1.22.1, es-abstract@npm:^1.22.3, es-abstract@npm:^1.23.0, es-abstract@npm:^1.23.1, es-abstract@npm:^1.23.2": + version: 1.23.3 + resolution: "es-abstract@npm:1.23.3" + dependencies: + array-buffer-byte-length: ^1.0.1 + arraybuffer.prototype.slice: ^1.0.3 + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 + data-view-buffer: ^1.0.1 + data-view-byte-length: ^1.0.1 + data-view-byte-offset: ^1.0.0 + es-define-property: ^1.0.0 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + es-set-tostringtag: ^2.0.3 + es-to-primitive: ^1.2.1 + function.prototype.name: ^1.1.6 + get-intrinsic: ^1.2.4 + get-symbol-description: ^1.0.2 + globalthis: ^1.0.3 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 + has-symbols: ^1.0.3 + hasown: ^2.0.2 + internal-slot: ^1.0.7 + is-array-buffer: ^3.0.4 + is-callable: ^1.2.7 + is-data-view: ^1.0.1 + is-negative-zero: ^2.0.3 + is-regex: ^1.1.4 + is-shared-array-buffer: ^1.0.3 + is-string: ^1.0.7 + is-typed-array: ^1.1.13 + is-weakref: ^1.0.2 + object-inspect: ^1.13.1 + object-keys: ^1.1.1 + object.assign: ^4.1.5 + regexp.prototype.flags: ^1.5.2 + safe-array-concat: ^1.1.2 + safe-regex-test: ^1.0.3 + string.prototype.trim: ^1.2.9 + string.prototype.trimend: ^1.0.8 + string.prototype.trimstart: ^1.0.8 + typed-array-buffer: ^1.0.2 + typed-array-byte-length: ^1.0.1 + typed-array-byte-offset: ^1.0.2 + typed-array-length: ^1.0.6 + unbox-primitive: ^1.0.2 + which-typed-array: ^1.1.15 + checksum: f840cf161224252512f9527306b57117192696571e07920f777cb893454e32999206198b4f075516112af6459daca282826d1735c450528470356d09eff3a9ae + languageName: node + linkType: hard + "es-array-method-boxes-properly@npm:^1.0.0": version: 1.0.0 resolution: "es-array-method-boxes-properly@npm:1.0.0" @@ -7681,6 +8254,73 @@ __metadata: languageName: node linkType: hard +"es-define-property@npm:^1.0.0": + version: 1.0.0 + resolution: "es-define-property@npm:1.0.0" + dependencies: + get-intrinsic: ^1.2.4 + checksum: f66ece0a887b6dca71848fa71f70461357c0e4e7249696f81bad0a1f347eed7b31262af4a29f5d726dc026426f085483b6b90301855e647aa8e21936f07293c6 + languageName: node + linkType: hard + +"es-errors@npm:^1.1.0, es-errors@npm:^1.2.1, es-errors@npm:^1.3.0": + version: 1.3.0 + resolution: "es-errors@npm:1.3.0" + checksum: ec1414527a0ccacd7f15f4a3bc66e215f04f595ba23ca75cdae0927af099b5ec865f9f4d33e9d7e86f512f252876ac77d4281a7871531a50678132429b1271b5 + languageName: node + linkType: hard + +"es-iterator-helpers@npm:^1.0.15, es-iterator-helpers@npm:^1.0.17": + version: 1.0.18 + resolution: "es-iterator-helpers@npm:1.0.18" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.0 + es-errors: ^1.3.0 + es-set-tostringtag: ^2.0.3 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + globalthis: ^1.0.3 + has-property-descriptors: ^1.0.2 + has-proto: ^1.0.3 + has-symbols: ^1.0.3 + internal-slot: ^1.0.7 + iterator.prototype: ^1.1.2 + safe-array-concat: ^1.1.2 + checksum: 1594324ff3ca8890fe30c98b2419d3007d2b14b35f9773f188114408ff973e13c526f6045d88209e932f58dc0c55fc9a4ae1554636f8938ed7d926ffc27d3e1a + languageName: node + linkType: hard + +"es-object-atoms@npm:^1.0.0": + version: 1.0.0 + resolution: "es-object-atoms@npm:1.0.0" + dependencies: + es-errors: ^1.3.0 + checksum: 26f0ff78ab93b63394e8403c353842b2272836968de4eafe97656adfb8a7c84b9099bf0fe96ed58f4a4cddc860f6e34c77f91649a58a5daa4a9c40b902744e3c + languageName: node + linkType: hard + +"es-set-tostringtag@npm:^2.0.3": + version: 2.0.3 + resolution: "es-set-tostringtag@npm:2.0.3" + dependencies: + get-intrinsic: ^1.2.4 + has-tostringtag: ^1.0.2 + hasown: ^2.0.1 + checksum: 7227fa48a41c0ce83e0377b11130d324ac797390688135b8da5c28994c0165be8b252e15cd1de41e1325e5a5412511586960213e88f9ab4a5e7d028895db5129 + languageName: node + linkType: hard + +"es-shim-unscopables@npm:^1.0.0, es-shim-unscopables@npm:^1.0.2": + version: 1.0.2 + resolution: "es-shim-unscopables@npm:1.0.2" + dependencies: + hasown: ^2.0.0 + checksum: 432bd527c62065da09ed1d37a3f8e623c423683285e6188108286f4a1e8e164a5bcbfbc0051557c7d14633cd2a41ce24c7048e6bbb66a985413fd32f1be72626 + languageName: node + linkType: hard + "es-to-primitive@npm:^1.2.1": version: 1.2.1 resolution: "es-to-primitive@npm:1.2.1" @@ -7742,6 +8382,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.0.2": + version: 3.1.2 + resolution: "escalade@npm:3.1.2" + checksum: 1ec0977aa2772075493002bdbd549d595ff6e9393b1cb0d7d6fcaf78c750da0c158f180938365486f75cb69fba20294351caddfce1b46552a7b6c3cde52eaa02 + languageName: node + linkType: hard + "escalade@npm:^3.1.1": version: 3.1.1 resolution: "escalade@npm:3.1.1" @@ -7763,14 +8410,21 @@ __metadata: languageName: node linkType: hard -"escape-string-regexp@npm:^1.0.2, escape-string-regexp@npm:^1.0.5": +"escape-string-regexp@npm:^1.0.5": version: 1.0.5 resolution: "escape-string-regexp@npm:1.0.5" checksum: 6092fda75c63b110c706b6a9bfde8a612ad595b628f0bd2147eea1d3406723020810e591effc7db1da91d80a71a737a313567c5abb3813e8d9c71f4aa595b410 languageName: node linkType: hard -"escodegen@npm:^1.11.0, escodegen@npm:^1.9.1": +"escape-string-regexp@npm:^4.0.0": + version: 4.0.0 + resolution: "escape-string-regexp@npm:4.0.0" + checksum: 98b48897d93060f2322108bf29db0feba7dd774be96cd069458d1453347b25ce8682ecc39859d4bca2203cc0ab19c237bcc71755eff49a0f8d90beadeeba5cc5 + languageName: node + linkType: hard + +"escodegen@npm:^1.8.1": version: 1.14.3 resolution: "escodegen@npm:1.14.3" dependencies: @@ -7789,141 +8443,198 @@ __metadata: languageName: node linkType: hard -"eslint-config-react-app@npm:^5.2.1": - version: 5.2.1 - resolution: "eslint-config-react-app@npm:5.2.1" +"escodegen@npm:^2.0.0": + version: 2.1.0 + resolution: "escodegen@npm:2.1.0" dependencies: - confusing-browser-globals: ^1.0.9 - peerDependencies: - "@typescript-eslint/eslint-plugin": 2.x - "@typescript-eslint/parser": 2.x - babel-eslint: 10.x - eslint: 6.x - eslint-plugin-flowtype: 3.x || 4.x - eslint-plugin-import: 2.x - eslint-plugin-jsx-a11y: 6.x - eslint-plugin-react: 7.x - eslint-plugin-react-hooks: 1.x || 2.x - checksum: 8af6801f29d7314611e111a1593e91d412d41cde6719303ee6db7de65d78ed4b53e9197497765bb2deed65e6bfd73bf7e74da58cab3f66838c2927880b21eeba + esprima: ^4.0.1 + estraverse: ^5.2.0 + esutils: ^2.0.2 + source-map: ~0.6.1 + dependenciesMeta: + source-map: + optional: true + bin: + escodegen: bin/escodegen.js + esgenerate: bin/esgenerate.js + checksum: 096696407e161305cd05aebb95134ad176708bc5cb13d0dcc89a5fcbb959b8ed757e7f2591a5f8036f8f4952d4a724de0df14cd419e29212729fa6df5ce16bf6 languageName: node linkType: hard -"eslint-import-resolver-node@npm:^0.3.2": - version: 0.3.4 - resolution: "eslint-import-resolver-node@npm:0.3.4" +"eslint-config-react-app@npm:^6.0.0": + version: 6.0.0 + resolution: "eslint-config-react-app@npm:6.0.0" dependencies: - debug: ^2.6.9 - resolve: ^1.13.1 - checksum: a0db55ec26c5bb385c8681af6b8d6dee16768d5f27dff72c3113407d0f028f28e56dcb1cc3a4689c79396a5f6a9c24bd0cac9a2c9c588c7d7357d24a42bec876 + confusing-browser-globals: ^1.0.10 + peerDependencies: + "@typescript-eslint/eslint-plugin": ^4.0.0 + "@typescript-eslint/parser": ^4.0.0 + babel-eslint: ^10.0.0 + eslint: ^7.5.0 + eslint-plugin-flowtype: ^5.2.0 + eslint-plugin-import: ^2.22.0 + eslint-plugin-jest: ^24.0.0 + eslint-plugin-jsx-a11y: ^6.3.1 + eslint-plugin-react: ^7.20.3 + eslint-plugin-react-hooks: ^4.0.8 + eslint-plugin-testing-library: ^3.9.0 + peerDependenciesMeta: + eslint-plugin-jest: + optional: true + eslint-plugin-testing-library: + optional: true + checksum: b265852455b1c10e9c5f0cebe199306fffc7f8e1b6548fcb0bccdc4415c288dfee8ab10717122a32275b91130dfb482dcbbc87d2fb79d8728d4c2bfa889f0915 languageName: node linkType: hard -"eslint-loader@npm:3.0.3": - version: 3.0.3 - resolution: "eslint-loader@npm:3.0.3" +"eslint-import-resolver-node@npm:^0.3.9": + version: 0.3.9 + resolution: "eslint-import-resolver-node@npm:0.3.9" dependencies: - fs-extra: ^8.1.0 - loader-fs-cache: ^1.0.2 - loader-utils: ^1.2.3 - object-hash: ^2.0.1 - schema-utils: ^2.6.1 - peerDependencies: - eslint: ^5.0.0 || ^6.0.0 - webpack: ^4.0.0 || ^5.0.0 - checksum: 5151ec134e26fb7caa20c4e7cf443e4400a48092008f8adebb7fef8ad4a6301d8f19a9f9c5aa78fec65b2d2594037edaef4ceae4769230cd7912566cd4ec7970 + debug: ^3.2.7 + is-core-module: ^2.13.0 + resolve: ^1.22.4 + checksum: 439b91271236b452d478d0522a44482e8c8540bf9df9bd744062ebb89ab45727a3acd03366a6ba2bdbcde8f9f718bab7fe8db64688aca75acf37e04eafd25e22 languageName: node linkType: hard -"eslint-module-utils@npm:^2.4.1": - version: 2.6.1 - resolution: "eslint-module-utils@npm:2.6.1" +"eslint-module-utils@npm:^2.8.0": + version: 2.8.1 + resolution: "eslint-module-utils@npm:2.8.1" dependencies: debug: ^3.2.7 - pkg-dir: ^2.0.0 - checksum: 3cc43a36a0075d300db6a3946203ec92249b6da1539694ef205a43b4ccfbc2eaf4961475d4b89c24b12c187d6bfd882c7c7d0b2ce02adb40c2dedb7fd022a7e2 + peerDependenciesMeta: + eslint: + optional: true + checksum: 3cecd99b6baf45ffc269167da0f95dcb75e5aa67b93d73a3bab63e2a7eedd9cdd6f188eed048e2f57c1b77db82c9cbf2adac20b512fa70e597d863dd3720170d languageName: node linkType: hard -"eslint-plugin-flowtype@npm:4.6.0": - version: 4.6.0 - resolution: "eslint-plugin-flowtype@npm:4.6.0" +"eslint-plugin-flowtype@npm:^5.2.0": + version: 5.10.0 + resolution: "eslint-plugin-flowtype@npm:5.10.0" dependencies: lodash: ^4.17.15 + string-natural-compare: ^3.0.1 peerDependencies: - eslint: ">=6.1.0" - checksum: 2256be93a2b49b9440defea2823349b0d3c428437c1e8868fb02d7f21a5d7ab48e53d8afb05fea713da2c3ee8c0d3dbe6e8c9efc798a86aebdb0cffc0f9dfc7a + eslint: ^7.1.0 + checksum: 791cd53c886bf819d52d6353cdfb4d49276dcd8a14f564a85d275d5017d81c7b1cc1921013ac9749f69c3f1bc4d23f36182137aab42bc059c2ae3f9773dd7740 languageName: node linkType: hard -"eslint-plugin-import@npm:2.20.1": - version: 2.20.1 - resolution: "eslint-plugin-import@npm:2.20.1" - dependencies: - array-includes: ^3.0.3 - array.prototype.flat: ^1.2.1 - contains-path: ^0.1.0 - debug: ^2.6.9 - doctrine: 1.5.0 - eslint-import-resolver-node: ^0.3.2 - eslint-module-utils: ^2.4.1 - has: ^1.0.3 - minimatch: ^3.0.4 - object.values: ^1.1.0 - read-pkg-up: ^2.0.0 - resolve: ^1.12.0 +"eslint-plugin-import@npm:^2.22.1": + version: 2.29.1 + resolution: "eslint-plugin-import@npm:2.29.1" + dependencies: + array-includes: ^3.1.7 + array.prototype.findlastindex: ^1.2.3 + array.prototype.flat: ^1.3.2 + array.prototype.flatmap: ^1.3.2 + debug: ^3.2.7 + doctrine: ^2.1.0 + eslint-import-resolver-node: ^0.3.9 + eslint-module-utils: ^2.8.0 + hasown: ^2.0.0 + is-core-module: ^2.13.1 + is-glob: ^4.0.3 + minimatch: ^3.1.2 + object.fromentries: ^2.0.7 + object.groupby: ^1.0.1 + object.values: ^1.1.7 + semver: ^6.3.1 + tsconfig-paths: ^3.15.0 peerDependencies: - eslint: 2.x - 6.x - checksum: 9c2f06fb5907afa12023df8b7b881ee345b11ba0930891966de5d009932bce4af7d1a8749037e15435d189796b26ba7190456d90a4ee7a8ce661e021a8b833d4 + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + checksum: e65159aef808136d26d029b71c8c6e4cb5c628e65e5de77f1eb4c13a379315ae55c9c3afa847f43f4ff9df7e54515c77ffc6489c6a6f81f7dd7359267577468c languageName: node linkType: hard -"eslint-plugin-jsx-a11y@npm:6.2.3": - version: 6.2.3 - resolution: "eslint-plugin-jsx-a11y@npm:6.2.3" - dependencies: - "@babel/runtime": ^7.4.5 - aria-query: ^3.0.0 - array-includes: ^3.0.3 - ast-types-flow: ^0.0.7 - axobject-query: ^2.0.2 - damerau-levenshtein: ^1.0.4 - emoji-regex: ^7.0.2 - has: ^1.0.3 - jsx-ast-utils: ^2.2.1 +"eslint-plugin-jest@npm:^24.1.0": + version: 24.7.0 + resolution: "eslint-plugin-jest@npm:24.7.0" + dependencies: + "@typescript-eslint/experimental-utils": ^4.0.1 peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 - checksum: 2e9f0ff28567e141479968a860f5670009a403250054970c714bf723e1f8c9ae7cddeb2bf13ee9f6882af333588645a06c10a417aa2733084813d162dec6c235 + "@typescript-eslint/eslint-plugin": ">= 4" + eslint: ">=5" + peerDependenciesMeta: + "@typescript-eslint/eslint-plugin": + optional: true + checksum: a4056582825ab3359d2e0e3aae50518f6f867d1cfb3240496605247d3ff9c84b4164f1a7e1f7087d5a2eae1343d738ada1ba74c422b13ad20b737601dc47ae08 languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^1.6.1": - version: 1.7.0 - resolution: "eslint-plugin-react-hooks@npm:1.7.0" +"eslint-plugin-jsx-a11y@npm:^6.3.1": + version: 6.8.0 + resolution: "eslint-plugin-jsx-a11y@npm:6.8.0" + dependencies: + "@babel/runtime": ^7.23.2 + aria-query: ^5.3.0 + array-includes: ^3.1.7 + array.prototype.flatmap: ^1.3.2 + ast-types-flow: ^0.0.8 + axe-core: =4.7.0 + axobject-query: ^3.2.1 + damerau-levenshtein: ^1.0.8 + emoji-regex: ^9.2.2 + es-iterator-helpers: ^1.0.15 + hasown: ^2.0.0 + jsx-ast-utils: ^3.3.5 + language-tags: ^1.0.9 + minimatch: ^3.1.2 + object.entries: ^1.1.7 + object.fromentries: ^2.0.7 peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - checksum: ea16d0cf4aaa0a30db05860bd892f3432a4cc299983a5adece092c021c4ee359e7e7277ff1e7207d1f550fae5f08a8b3aa2698f36e82cdebb756a8a3e1c842eb + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 3dec00e2a3089c4c61ac062e4196a70985fb7eda1fd67fe035363d92578debde92fdb8ed2e472321fc0d71e75f4a1e8888c6a3218c14dd93c8e8d19eb6f51554 languageName: node linkType: hard -"eslint-plugin-react@npm:7.19.0": - version: 7.19.0 - resolution: "eslint-plugin-react@npm:7.19.0" +"eslint-plugin-react-hooks@npm:^4.2.0": + version: 4.6.0 + resolution: "eslint-plugin-react-hooks@npm:4.6.0" + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + checksum: 23001801f14c1d16bf0a837ca7970d9dd94e7b560384b41db378b49b6e32dc43d6e2790de1bd737a652a86f81a08d6a91f402525061b47719328f586a57e86c3 + languageName: node + linkType: hard + +"eslint-plugin-react@npm:^7.21.5": + version: 7.34.1 + resolution: "eslint-plugin-react@npm:7.34.1" dependencies: - array-includes: ^3.1.1 + array-includes: ^3.1.7 + array.prototype.findlast: ^1.2.4 + array.prototype.flatmap: ^1.3.2 + array.prototype.toreversed: ^1.1.2 + array.prototype.tosorted: ^1.1.3 doctrine: ^2.1.0 - has: ^1.0.3 - jsx-ast-utils: ^2.2.3 - object.entries: ^1.1.1 - object.fromentries: ^2.0.2 - object.values: ^1.1.1 - prop-types: ^15.7.2 - resolve: ^1.15.1 - semver: ^6.3.0 - string.prototype.matchall: ^4.0.2 - xregexp: ^4.3.0 + es-iterator-helpers: ^1.0.17 + estraverse: ^5.3.0 + jsx-ast-utils: ^2.4.1 || ^3.0.0 + minimatch: ^3.1.2 + object.entries: ^1.1.7 + object.fromentries: ^2.0.7 + object.hasown: ^1.1.3 + object.values: ^1.1.7 + prop-types: ^15.8.1 + resolve: ^2.0.0-next.5 + semver: ^6.3.1 + string.prototype.matchall: ^4.0.10 + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 + checksum: 82f391c5a093235c3bc2f664c54e009c49460778ee7d1b86c1536df9ac4d2a80d1dedc9241ac797df4a9dced936e955d9c89042fb3ac8d017b5359d1320d3c0f + languageName: node + linkType: hard + +"eslint-plugin-testing-library@npm:^3.9.2": + version: 3.10.2 + resolution: "eslint-plugin-testing-library@npm:3.10.2" + dependencies: + "@typescript-eslint/experimental-utils": ^3.10.1 peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 - checksum: c15bc7aa27670ceb1410e9c703072c13d8cd6117af92fcdffcc531bbaf4e4ae4266f52583779178a71c7f917860ac7cce4677e4dd428d3d1f9883fe3a819e81e + eslint: ^5 || ^6 || ^7 + checksum: 3859d4a4816b130cfefc3b45bc7d303aff19b8d4e83a5e35ca3d634de9f3c4aa1b4340cb4f41e2d1bfe70b173562b9882c58ac48be4e07ddf6a1f88659e2604d languageName: node linkType: hard @@ -7947,12 +8658,12 @@ __metadata: languageName: node linkType: hard -"eslint-utils@npm:^1.4.3": - version: 1.4.3 - resolution: "eslint-utils@npm:1.4.3" +"eslint-utils@npm:^2.0.0, eslint-utils@npm:^2.1.0": + version: 2.1.0 + resolution: "eslint-utils@npm:2.1.0" dependencies: eslint-visitor-keys: ^1.1.0 - checksum: a20630e686034107138272f245c460f6d77705d1f4bb0628c1a1faf59fc800f441188916b3ec3b957394dc405aa200a3017dfa2b0fff0976e307a4e645a18d1e + checksum: 27500938f348da42100d9e6ad03ae29b3de19ba757ae1a7f4a087bdcf83ac60949bbb54286492ca61fac1f5f3ac8692dd21537ce6214240bf95ad0122f24d71d languageName: node linkType: hard @@ -7967,7 +8678,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^1.0.0, eslint-visitor-keys@npm:^1.1.0": +"eslint-visitor-keys@npm:^1.0.0, eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": version: 1.3.0 resolution: "eslint-visitor-keys@npm:1.3.0" checksum: 37a19b712f42f4c9027e8ba98c2b06031c17e0c0a4c696cd429bd9ee04eb43889c446f2cd545e1ff51bef9593fcec94ecd2c2ef89129fcbbf3adadbef520376a @@ -7981,50 +8692,70 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^6.6.0": - version: 6.8.0 - resolution: "eslint@npm:6.8.0" +"eslint-webpack-plugin@npm:^2.1.0": + version: 2.7.0 + resolution: "eslint-webpack-plugin@npm:2.7.0" dependencies: - "@babel/code-frame": ^7.0.0 + "@types/eslint": ^7.29.0 + arrify: ^2.0.1 + jest-worker: ^27.5.1 + micromatch: ^4.0.5 + normalize-path: ^3.0.0 + schema-utils: ^3.1.1 + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + webpack: ^4.0.0 || ^5.0.0 + checksum: b6fd7cf4c49078b345a908b82b0bee06bc82ab0cec214ddd5fe5bb18b065765d52a07ad4077f6bba5830ba2f55f37d8f2208a52d11f34ee29df81153e3124d9c + languageName: node + linkType: hard + +"eslint@npm:^7.11.0": + version: 7.32.0 + resolution: "eslint@npm:7.32.0" + dependencies: + "@babel/code-frame": 7.12.11 + "@eslint/eslintrc": ^0.4.3 + "@humanwhocodes/config-array": ^0.5.0 ajv: ^6.10.0 - chalk: ^2.1.0 - cross-spawn: ^6.0.5 + chalk: ^4.0.0 + cross-spawn: ^7.0.2 debug: ^4.0.1 doctrine: ^3.0.0 - eslint-scope: ^5.0.0 - eslint-utils: ^1.4.3 - eslint-visitor-keys: ^1.1.0 - espree: ^6.1.2 - esquery: ^1.0.1 + enquirer: ^2.3.5 + escape-string-regexp: ^4.0.0 + eslint-scope: ^5.1.1 + eslint-utils: ^2.1.0 + eslint-visitor-keys: ^2.0.0 + espree: ^7.3.1 + esquery: ^1.4.0 esutils: ^2.0.2 - file-entry-cache: ^5.0.1 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^6.0.1 functional-red-black-tree: ^1.0.1 - glob-parent: ^5.0.0 - globals: ^12.1.0 + glob-parent: ^5.1.2 + globals: ^13.6.0 ignore: ^4.0.6 import-fresh: ^3.0.0 imurmurhash: ^0.1.4 - inquirer: ^7.0.0 is-glob: ^4.0.0 js-yaml: ^3.13.1 json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.3.0 - lodash: ^4.17.14 + levn: ^0.4.1 + lodash.merge: ^4.6.2 minimatch: ^3.0.4 - mkdirp: ^0.5.1 natural-compare: ^1.4.0 - optionator: ^0.8.3 + optionator: ^0.9.1 progress: ^2.0.0 - regexpp: ^2.0.1 - semver: ^6.1.2 - strip-ansi: ^5.2.0 - strip-json-comments: ^3.0.1 - table: ^5.2.3 + regexpp: ^3.1.0 + semver: ^7.2.1 + strip-ansi: ^6.0.0 + strip-json-comments: ^3.1.0 + table: ^6.0.9 text-table: ^0.2.0 v8-compile-cache: ^2.0.3 bin: - eslint: ./bin/eslint.js - checksum: d4edbe69589ef194e7d3470a18632560c5399a5f685295bd59a11cddba4c6f7e03a137a15a21389f8f85712ebd82d0a628ee4e9cd4391113556029c486616e25 + eslint: bin/eslint.js + checksum: cc85af9985a3a11085c011f3d27abe8111006d34cc274291b3c4d7bea51a4e2ff6135780249becd919ba7f6d6d1ecc38a6b73dacb6a7be08d38453b344dc8d37 languageName: node linkType: hard @@ -8040,14 +8771,24 @@ __metadata: languageName: node linkType: hard -"espree@npm:^6.1.2": - version: 6.2.1 - resolution: "espree@npm:6.2.1" +"espree@npm:^7.3.0, espree@npm:^7.3.1": + version: 7.3.1 + resolution: "espree@npm:7.3.1" dependencies: - acorn: ^7.1.1 - acorn-jsx: ^5.2.0 - eslint-visitor-keys: ^1.1.0 - checksum: 99c508950b5b9f53d008d781d2abb7a4ef3496ea699306fb6eb737c7e513aa594644314364c50ec27abb220124c6851fff64a6b62c358479534369904849360b + acorn: ^7.4.0 + acorn-jsx: ^5.3.1 + eslint-visitor-keys: ^1.3.0 + checksum: aa9b50dcce883449af2e23bc2b8d9abb77118f96f4cb313935d6b220f77137eaef7724a83c3f6243b96bc0e4ab14766198e60818caad99f9519ae5a336a39b45 + languageName: node + linkType: hard + +"esprima@npm:1.2.2": + version: 1.2.2 + resolution: "esprima@npm:1.2.2" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 4f10006f0e315f2f7d8cf6630e465f183512f1ab2e862b11785a133ce37ed1696573deefb5256e510eaa4368342b13b393334477f6ccdcdb8f10e782b0f5e6dc languageName: node linkType: hard @@ -8070,6 +8811,15 @@ __metadata: languageName: node linkType: hard +"esquery@npm:^1.4.0": + version: 1.5.0 + resolution: "esquery@npm:1.5.0" + dependencies: + estraverse: ^5.1.0 + checksum: aefb0d2596c230118656cd4ec7532d447333a410a48834d80ea648b1e7b5c9bc9ed8b5e33a89cb04e487b60d622f44cf5713bf4abed7c97343edefdc84a35900 + languageName: node + linkType: hard + "esrecurse@npm:^4.1.0, esrecurse@npm:^4.3.0": version: 4.3.0 resolution: "esrecurse@npm:4.3.0" @@ -8093,6 +8843,27 @@ __metadata: languageName: node linkType: hard +"estraverse@npm:^5.3.0": + version: 5.3.0 + resolution: "estraverse@npm:5.3.0" + checksum: 072780882dc8416ad144f8fe199628d2b3e7bbc9989d9ed43795d2c90309a2047e6bc5979d7e2322a341163d22cfad9e21f4110597fe487519697389497e4e2b + languageName: node + linkType: hard + +"estree-walker@npm:^0.6.1": + version: 0.6.1 + resolution: "estree-walker@npm:0.6.1" + checksum: 9d6f82a4921f11eec18f8089fb3cce6e53bcf45a8e545c42a2674d02d055fb30f25f90495f8be60803df6c39680c80dcee7f944526867eb7aa1fc9254883b23d + languageName: node + linkType: hard + +"estree-walker@npm:^1.0.1": + version: 1.0.1 + resolution: "estree-walker@npm:1.0.1" + checksum: 7e70da539691f6db03a08e7ce94f394ce2eef4180e136d251af299d41f92fb2d28ebcd9a6e393e3728d7970aeb5358705ddf7209d52fbcb2dd4693f95dcf925f + languageName: node + linkType: hard + "esutils@npm:^2.0.2": version: 2.0.3 resolution: "esutils@npm:2.0.3" @@ -8163,7 +8934,7 @@ __metadata: languageName: node linkType: hard -"execa@npm:4.1.0": +"execa@npm:4.1.0, execa@npm:^4.0.0": version: 4.1.0 resolution: "execa@npm:4.1.0" dependencies: @@ -8226,17 +8997,17 @@ __metadata: languageName: node linkType: hard -"expect@npm:^24.9.0": - version: 24.9.0 - resolution: "expect@npm:24.9.0" +"expect@npm:^26.6.0, expect@npm:^26.6.2": + version: 26.6.2 + resolution: "expect@npm:26.6.2" dependencies: - "@jest/types": ^24.9.0 - ansi-styles: ^3.2.0 - jest-get-type: ^24.9.0 - jest-matcher-utils: ^24.9.0 - jest-message-util: ^24.9.0 - jest-regex-util: ^24.9.0 - checksum: bfce2243543dd10e3c2047bbe6fc99b7b150cea71b198ddd8feb2e7ebfef1a3dd46ec7519e05d23a20b30c242b13dad97551368a690731d9a591f6f863528cee + "@jest/types": ^26.6.2 + ansi-styles: ^4.0.0 + jest-get-type: ^26.3.0 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-regex-util: ^26.0.0 + checksum: 79a9b888c5c6d37d11f2cb76def6cf1dc8ff098d38662ee20c9f2ee0da67e9a93435f2327854b2e7554732153870621843e7f83e8cefb1250447ee2bc39883a4 languageName: node linkType: hard @@ -8323,17 +9094,6 @@ __metadata: languageName: node linkType: hard -"external-editor@npm:^3.0.3": - version: 3.1.0 - resolution: "external-editor@npm:3.1.0" - dependencies: - chardet: ^0.7.0 - iconv-lite: ^0.4.24 - tmp: ^0.0.33 - checksum: 1c2a616a73f1b3435ce04030261bed0e22d4737e14b090bb48e58865da92529c9f2b05b893de650738d55e692d071819b45e1669259b2b354bc3154d27a698c7 - languageName: node - linkType: hard - "extglob@npm:^2.0.4": version: 2.0.4 resolution: "extglob@npm:2.0.4" @@ -8381,48 +9141,34 @@ __metadata: languageName: node linkType: hard -"fast-deep-equal@npm:^3.1.1": +"fast-deep-equal@npm:^3.1.1, fast-deep-equal@npm:^3.1.3": version: 3.1.3 resolution: "fast-deep-equal@npm:3.1.3" checksum: e21a9d8d84f53493b6aa15efc9cfd53dd5b714a1f23f67fb5dc8f574af80df889b3bce25dc081887c6d25457cce704e636395333abad896ccdec03abaf1f3f9d languageName: node linkType: hard -"fast-glob@npm:^2.0.2": - version: 2.2.7 - resolution: "fast-glob@npm:2.2.7" - dependencies: - "@mrmlnc/readdir-enhanced": ^2.2.1 - "@nodelib/fs.stat": ^1.1.2 - glob-parent: ^3.1.0 - is-glob: ^4.0.0 - merge2: ^1.2.3 - micromatch: ^3.1.10 - checksum: 304ccff1d437fcc44ae0168b0c3899054b92e0fd6af6ad7c3ccc82ab4ddd210b99c7c739d60ee3686da2aa165cd1a31810b31fd91f7c2a575d297342a9fc0534 - languageName: node - linkType: hard - -"fast-glob@npm:^3.2.9": - version: 3.3.1 - resolution: "fast-glob@npm:3.3.1" +"fast-glob@npm:^3.1.1, fast-glob@npm:^3.2.9": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" dependencies: "@nodelib/fs.stat": ^2.0.2 "@nodelib/fs.walk": ^1.2.3 glob-parent: ^5.1.2 merge2: ^1.3.0 micromatch: ^4.0.4 - checksum: b6f3add6403e02cf3a798bfbb1183d0f6da2afd368f27456010c0bc1f9640aea308243d4cb2c0ab142f618276e65ecb8be1661d7c62a7b4e5ba774b9ce5432e5 + checksum: 900e4979f4dbc3313840078419245621259f349950411ca2fa445a2f9a1a6d98c3b5e7e0660c5ccd563aa61abe133a21765c6c0dec8e57da1ba71d8000b05ec1 languageName: node linkType: hard -"fast-json-stable-stringify@npm:^2.0.0": +"fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" checksum: b191531e36c607977e5b1c47811158733c34ccb3bfde92c44798929e9b4154884378536d26ad90dfecd32e1ffc09c545d23535ad91b3161a27ddbb8ebe0cbecb languageName: node linkType: hard -"fast-levenshtein@npm:~2.0.6": +"fast-levenshtein@npm:^2.0.6, fast-levenshtein@npm:~2.0.6": version: 2.0.6 resolution: "fast-levenshtein@npm:2.0.6" checksum: 92cfec0a8dfafd9c7a15fba8f2cc29cd0b62b85f056d99ce448bbcd9f708e18ab2764bda4dd5158364f4145a7c72788538994f0d1787b956ef0d1062b0f7c24c @@ -8430,11 +9176,11 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.11.0 - resolution: "fastq@npm:1.11.0" + version: 1.17.1 + resolution: "fastq@npm:1.17.1" dependencies: reusify: ^1.0.4 - checksum: 9db0ceea9280c5f207da40c562a4e574913c18933cd74b880b01bf8e81a9a6e368ec71e89c9c1b9f4066d0275cc22600efd6dde87f713217acbf67076481734b + checksum: a8c5b26788d5a1763f88bae56a8ddeee579f935a831c5fe7a8268cea5b0a91fbfe705f612209e02d639b881d7b48e461a50da4a10cfaa40da5ca7cc9da098d88 languageName: node linkType: hard @@ -8519,7 +9265,7 @@ __metadata: languageName: node linkType: hard -"figures@npm:^3.0.0, figures@npm:^3.2.0": +"figures@npm:^3.2.0": version: 3.2.0 resolution: "figures@npm:3.2.0" dependencies: @@ -8528,24 +9274,24 @@ __metadata: languageName: node linkType: hard -"file-entry-cache@npm:^5.0.1": - version: 5.0.1 - resolution: "file-entry-cache@npm:5.0.1" +"file-entry-cache@npm:^6.0.1": + version: 6.0.1 + resolution: "file-entry-cache@npm:6.0.1" dependencies: - flat-cache: ^2.0.1 - checksum: 9014b17766815d59b8b789633aed005242ef857348c09be558bd85b4a24e16b0ad1e0e5229ccea7a2109f74ef1b3db1a559b58afe12b884f09019308711376fd + flat-cache: ^3.0.4 + checksum: f49701feaa6314c8127c3c2f6173cfefff17612f5ed2daaafc6da13b5c91fd43e3b2a58fd0d63f9f94478a501b167615931e7200e31485e320f74a33885a9c74 languageName: node linkType: hard -"file-loader@npm:4.3.0": - version: 4.3.0 - resolution: "file-loader@npm:4.3.0" +"file-loader@npm:6.1.1": + version: 6.1.1 + resolution: "file-loader@npm:6.1.1" dependencies: - loader-utils: ^1.2.3 - schema-utils: ^2.5.0 + loader-utils: ^2.0.0 + schema-utils: ^3.0.0 peerDependencies: - webpack: ^4.0.0 - checksum: a005ac5599e96631e8ead32db874283ef821c121e93997b0d6f853db1284bcd7832e1ac59d39a21c201de22b6e33146996c28bd8c486893a5191c334a00f61b2 + webpack: ^4.0.0 || ^5.0.0 + checksum: 6369da5af456b640599d7ede7a3a9a55e485138a7829c583313d5165d0984c3d337de3aebee32fdfa3295facb4a44b74a9c3c956b1e0e30e8c96152106ff4b23 languageName: node linkType: hard @@ -8563,10 +9309,10 @@ __metadata: languageName: node linkType: hard -"filesize@npm:6.0.1": - version: 6.0.1 - resolution: "filesize@npm:6.0.1" - checksum: 2e3f9b09a32086e068162a1caf4b6b438aba23389086bf77cf67c410698ed12baf01c928507777b8b2d3e1e2578f2e74f219608a0f7ea210a74e33082c0caab1 +"filesize@npm:6.1.0": + version: 6.1.0 + resolution: "filesize@npm:6.1.0" + checksum: c46d644cb562fba7b7e837d5cd339394492abaa06722018b91a97d2a63b6c753ef30653de5c03bf178c631185bf55c3561c28fa9ccc4e9755f42d853c6ed4d09 languageName: node linkType: hard @@ -8606,17 +9352,6 @@ __metadata: languageName: node linkType: hard -"find-cache-dir@npm:^0.1.1": - version: 0.1.1 - resolution: "find-cache-dir@npm:0.1.1" - dependencies: - commondir: ^1.0.1 - mkdirp: ^0.5.1 - pkg-dir: ^1.0.0 - checksum: b5d9d68c1ff8c222124bb19089a405be9a3d0333e713ae989d980342c35690dfddd05f0fb456ec11846579e30e0f0e18293d20632662506cd2fa2c7237783479 - languageName: node - linkType: hard - "find-cache-dir@npm:^2.1.0": version: 2.1.0 resolution: "find-cache-dir@npm:2.1.0" @@ -8649,25 +9384,6 @@ __metadata: languageName: node linkType: hard -"find-up@npm:^1.0.0": - version: 1.1.2 - resolution: "find-up@npm:1.1.2" - dependencies: - path-exists: ^2.0.0 - pinkie-promise: ^2.0.0 - checksum: a2cb9f4c9f06ee3a1e92ed71d5aed41ac8ae30aefa568132f6c556fac7678a5035126153b59eaec68da78ac409eef02503b2b059706bdbf232668d7245e3240a - languageName: node - linkType: hard - -"find-up@npm:^2.0.0, find-up@npm:^2.1.0": - version: 2.1.0 - resolution: "find-up@npm:2.1.0" - dependencies: - locate-path: ^2.0.0 - checksum: 43284fe4da09f89011f08e3c32cd38401e786b19226ea440b75386c1b12a4cb738c94969808d53a84f564ede22f732c8409e3cfc3f7fb5b5c32378ad0bbf28bd - languageName: node - linkType: hard - "find-up@npm:^3.0.0": version: 3.0.0 resolution: "find-up@npm:3.0.0" @@ -8677,21 +9393,21 @@ __metadata: languageName: node linkType: hard -"flat-cache@npm:^2.0.1": - version: 2.0.1 - resolution: "flat-cache@npm:2.0.1" +"flat-cache@npm:^3.0.4": + version: 3.2.0 + resolution: "flat-cache@npm:3.2.0" dependencies: - flatted: ^2.0.0 - rimraf: 2.6.3 - write: 1.0.3 - checksum: 0f5e66467658039e6fcaaccb363b28f43906ba72fab7ff2a4f6fcd5b4899679e13ca46d9fc6cc48b68ac925ae93137106d4aaeb79874c13f21f87a361705f1b1 + flatted: ^3.2.9 + keyv: ^4.5.3 + rimraf: ^3.0.2 + checksum: e7e0f59801e288b54bee5cb9681e9ee21ee28ef309f886b312c9d08415b79fc0f24ac842f84356ce80f47d6a53de62197ce0e6e148dc42d5db005992e2a756ec languageName: node linkType: hard -"flatted@npm:^2.0.0": - version: 2.0.2 - resolution: "flatted@npm:2.0.2" - checksum: 473c754db7a529e125a22057098f1a4c905ba17b8cc269c3acf77352f0ffa6304c851eb75f6a1845f74461f560e635129ca6b0b8a78fb253c65cea4de3d776f2 +"flatted@npm:^3.2.9": + version: 3.3.1 + resolution: "flatted@npm:3.3.1" + checksum: 85ae7181650bb728c221e7644cbc9f4bf28bc556f2fc89bb21266962bdf0ce1029cc7acc44bb646cd469d9baac7c317f64e841c4c4c00516afa97320cdac7f94 languageName: node linkType: hard @@ -8712,7 +9428,7 @@ __metadata: languageName: node linkType: hard -"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.14.0": +"follow-redirects@npm:^1.0.0, follow-redirects@npm:^1.15.0": version: 1.15.6 resolution: "follow-redirects@npm:1.15.6" peerDependenciesMeta: @@ -8731,29 +9447,13 @@ __metadata: languageName: node linkType: hard -"for-in@npm:^0.1.3": - version: 0.1.8 - resolution: "for-in@npm:0.1.8" - checksum: f5bdad7811700ee6a0f96b33d72a1db966aea75a1f03c7245d147f8369305e709f53a55ee7ae8eaddcfa85c7c89bca78472be8f1bc605475ce5bb2c70f77f8da - languageName: node - linkType: hard - -"for-in@npm:^1.0.1, for-in@npm:^1.0.2": +"for-in@npm:^1.0.2": version: 1.0.2 resolution: "for-in@npm:1.0.2" checksum: 09f4ae93ce785d253ac963d94c7f3432d89398bf25ac7a24ed034ca393bf74380bdeccc40e0f2d721a895e54211b07c8fad7132e8157827f6f7f059b70b4043d languageName: node linkType: hard -"for-own@npm:^0.1.3": - version: 0.1.5 - resolution: "for-own@npm:0.1.5" - dependencies: - for-in: ^1.0.1 - checksum: 07eb0a2e98eb55ce13b56dd11ef4fb5e619ba7380aaec388b9eec1946153d74fa734ce409e8434020557e9489a50c34bc004d55754f5863bf7d77b441d8dee8c - languageName: node - linkType: hard - "forever-agent@npm:~0.6.1": version: 0.6.1 resolution: "forever-agent@npm:0.6.1" @@ -8761,19 +9461,40 @@ __metadata: languageName: node linkType: hard -"fork-ts-checker-webpack-plugin@npm:3.1.1": - version: 3.1.1 - resolution: "fork-ts-checker-webpack-plugin@npm:3.1.1" +"fork-ts-checker-webpack-plugin@npm:4.1.6": + version: 4.1.6 + resolution: "fork-ts-checker-webpack-plugin@npm:4.1.6" dependencies: - babel-code-frame: ^6.22.0 + "@babel/code-frame": ^7.5.5 chalk: ^2.4.1 - chokidar: ^3.3.0 micromatch: ^3.1.10 minimatch: ^3.0.4 semver: ^5.6.0 tapable: ^1.0.0 worker-rpc: ^0.1.0 - checksum: c7b278e569ec7d5a1c73808b80870dda87f6171dc33c7cf06090c441c54753e1a5886b8256269fd2e100cda980b3f12db02d02ae2008fc067c81e948a173f35f + checksum: 4cc4fa7919dd9a0d765514d064c86e3a6f9cea8e700996b3e775cfcc0280f606a2dd16203d9b7e294b64e900795b0d80eb41fc8c192857d3350e407f14ef3eed + languageName: node + linkType: hard + +"form-data@npm:^3.0.0": + version: 3.0.1 + resolution: "form-data@npm:3.0.1" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: b019e8d35c8afc14a2bd8a7a92fa4f525a4726b6d5a9740e8d2623c30e308fbb58dc8469f90415a856698933c8479b01646a9dff33c87cc4e76d72aedbbf860d + languageName: node + linkType: hard + +"form-data@npm:^4.0.0": + version: 4.0.0 + resolution: "form-data@npm:4.0.0" + dependencies: + asynckit: ^0.4.0 + combined-stream: ^1.0.8 + mime-types: ^2.1.12 + checksum: 01135bf8675f9d5c61ff18e2e2932f719ca4de964e3be90ef4c36aacfc7b9cb2fceb5eca0b7e0190e3383fe51c5b37f4cb80b62ca06a99aaabfcfd6ac7c9328c languageName: node linkType: hard @@ -8821,17 +9542,6 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^4.0.2": - version: 4.0.3 - resolution: "fs-extra@npm:4.0.3" - dependencies: - graceful-fs: ^4.1.2 - jsonfile: ^4.0.0 - universalify: ^0.1.0 - checksum: c5ae3c7043ad7187128e619c0371da01b58694c1ffa02c36fb3f5b459925d9c27c3cb1e095d9df0a34a85ca993d8b8ff6f6ecef868fd5ebb243548afa7fc0936 - languageName: node - linkType: hard - "fs-extra@npm:^7.0.0": version: 7.0.1 resolution: "fs-extra@npm:7.0.1" @@ -8854,7 +9564,7 @@ __metadata: languageName: node linkType: hard -"fs-extra@npm:^9.1.0": +"fs-extra@npm:^9.0.1, fs-extra@npm:^9.1.0": version: 9.1.0 resolution: "fs-extra@npm:9.1.0" dependencies: @@ -8894,16 +9604,6 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:2.1.2": - version: 2.1.2 - resolution: "fsevents@npm:2.1.2" - dependencies: - node-gyp: latest - checksum: 63fe1ba77b63d5da5dde6112c5f0eb161b9d18a61427a8a49d661eeed080189d99e8f9da11bb6b75ecd5129a69edc5757d60a4eb0bbada6de68d5156c382c5e1 - conditions: os=darwin - languageName: node - linkType: hard - "fsevents@npm:^1.2.7": version: 1.2.13 resolution: "fsevents@npm:1.2.13" @@ -8915,21 +9615,22 @@ __metadata: languageName: node linkType: hard -"fsevents@npm:~2.3.2": - version: 2.3.2 - resolution: "fsevents@npm:2.3.2" +"fsevents@npm:^2.1.2, fsevents@npm:^2.1.3": + version: 2.3.3 + resolution: "fsevents@npm:2.3.3" dependencies: node-gyp: latest - checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f + checksum: 11e6ea6fea15e42461fc55b4b0e4a0a3c654faa567f1877dbd353f39156f69def97a69936d1746619d656c4b93de2238bf731f6085a03a50cabf287c9d024317 conditions: os=darwin languageName: node linkType: hard -"fsevents@patch:fsevents@2.1.2#~builtin": - version: 2.1.2 - resolution: "fsevents@patch:fsevents@npm%3A2.1.2#~builtin::version=2.1.2&hash=18f3a7" +"fsevents@npm:~2.3.2": + version: 2.3.2 + resolution: "fsevents@npm:2.3.2" dependencies: node-gyp: latest + checksum: 97ade64e75091afee5265e6956cb72ba34db7819b4c3e94c431d4be2b19b8bb7a2d4116da417950c3425f17c8fe693d25e20212cac583ac1521ad066b77ae31f conditions: os=darwin languageName: node linkType: hard @@ -8944,6 +9645,15 @@ __metadata: languageName: node linkType: hard +"fsevents@patch:fsevents@^2.1.2#~builtin, fsevents@patch:fsevents@^2.1.3#~builtin": + version: 2.3.3 + resolution: "fsevents@patch:fsevents@npm%3A2.3.3#~builtin::version=2.3.3&hash=18f3a7" + dependencies: + node-gyp: latest + conditions: os=darwin + languageName: node + linkType: hard + "fsevents@patch:fsevents@~2.3.2#~builtin": version: 2.3.2 resolution: "fsevents@patch:fsevents@npm%3A2.3.2#~builtin::version=2.3.2&hash=18f3a7" @@ -8972,6 +9682,13 @@ __metadata: languageName: node linkType: hard +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 2b0ff4ce708d99715ad14a6d1f894e2a83242e4a52ccfcefaee5e40050562e5f6dafc1adbb4ce2d4ab47279a45dc736ab91ea5042d843c3c092820dfe032efb1 + languageName: node + linkType: hard + "function.prototype.name@npm:^1.1.2, function.prototype.name@npm:^1.1.3": version: 1.1.4 resolution: "function.prototype.name@npm:1.1.4" @@ -8984,6 +9701,18 @@ __metadata: languageName: node linkType: hard +"function.prototype.name@npm:^1.1.5, function.prototype.name@npm:^1.1.6": + version: 1.1.6 + resolution: "function.prototype.name@npm:1.1.6" + dependencies: + call-bind: ^1.0.2 + define-properties: ^1.2.0 + es-abstract: ^1.22.1 + functions-have-names: ^1.2.3 + checksum: 7a3f9bd98adab09a07f6e1f03da03d3f7c26abbdeaeee15223f6c04a9fb5674792bdf5e689dac19b97ac71de6aad2027ba3048a9b883aa1b3173eed6ab07f479 + languageName: node + linkType: hard + "functional-red-black-tree@npm:^1.0.1": version: 1.0.1 resolution: "functional-red-black-tree@npm:1.0.1" @@ -8998,20 +9727,10 @@ __metadata: languageName: node linkType: hard -"gauge@npm:^3.0.0": - version: 3.0.2 - resolution: "gauge@npm:3.0.2" - dependencies: - aproba: ^1.0.3 || ^2.0.0 - color-support: ^1.1.2 - console-control-strings: ^1.0.0 - has-unicode: ^2.0.1 - object-assign: ^4.1.1 - signal-exit: ^3.0.0 - string-width: ^4.2.3 - strip-ansi: ^6.0.1 - wide-align: ^1.1.2 - checksum: 81296c00c7410cdd48f997800155fbead4f32e4f82109be0719c63edc8560e6579946cc8abd04205297640691ec26d21b578837fd13a4e96288ab4b40b1dc3e9 +"functions-have-names@npm:^1.2.3": + version: 1.2.3 + resolution: "functions-have-names@npm:1.2.3" + checksum: c3f1f5ba20f4e962efb71344ce0a40722163e85bee2101ce25f88214e78182d2d2476aa85ef37950c579eb6cf6ee811c17b3101bb84004bb75655f3e33f3fdb5 languageName: node linkType: hard @@ -9048,13 +9767,6 @@ __metadata: languageName: node linkType: hard -"get-caller-file@npm:^1.0.1": - version: 1.0.3 - resolution: "get-caller-file@npm:1.0.3" - checksum: 2b90a7f848896abcebcdc0acc627a435bcf05b9cd280599bc980ebfcdc222416c3df12c24c4845f69adc4346728e8966f70b758f9369f3534182791dfbc25c05 - languageName: node - linkType: hard - "get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -9062,7 +9774,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1": +"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1": version: 1.1.1 resolution: "get-intrinsic@npm:1.1.1" dependencies: @@ -9073,6 +9785,19 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.3, get-intrinsic@npm:^1.2.4": + version: 1.2.4 + resolution: "get-intrinsic@npm:1.2.4" + dependencies: + es-errors: ^1.3.0 + function-bind: ^1.1.2 + has-proto: ^1.0.1 + has-symbols: ^1.0.3 + hasown: ^2.0.0 + checksum: 414e3cdf2c203d1b9d7d33111df746a4512a1aa622770b361dadddf8ed0b5aeb26c560f49ca077e24bfafb0acb55ca908d1f709216ccba33ffc548ec8a79a951 + languageName: node + linkType: hard + "get-own-enumerable-property-symbols@npm:^3.0.0": version: 3.0.2 resolution: "get-own-enumerable-property-symbols@npm:3.0.2" @@ -9080,6 +9805,13 @@ __metadata: languageName: node linkType: hard +"get-package-type@npm:^0.1.0": + version: 0.1.0 + resolution: "get-package-type@npm:0.1.0" + checksum: bba0811116d11e56d702682ddef7c73ba3481f114590e705fc549f4d868972263896af313c57a25c076e3c0d567e11d919a64ba1b30c879be985fc9d44f96148 + languageName: node + linkType: hard + "get-stdin@npm:^4.0.1": version: 4.0.1 resolution: "get-stdin@npm:4.0.1" @@ -9105,6 +9837,17 @@ __metadata: languageName: node linkType: hard +"get-symbol-description@npm:^1.0.2": + version: 1.0.2 + resolution: "get-symbol-description@npm:1.0.2" + dependencies: + call-bind: ^1.0.5 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + checksum: e1cb53bc211f9dbe9691a4f97a46837a553c4e7caadd0488dc24ac694db8a390b93edd412b48dcdd0b4bbb4c595de1709effc75fc87c0839deedc6968f5bd973 + languageName: node + linkType: hard + "get-value@npm:^2.0.3, get-value@npm:^2.0.6": version: 2.0.6 resolution: "get-value@npm:2.0.6" @@ -9140,7 +9883,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^5.0.0, glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": +"glob-parent@npm:^5.1.2, glob-parent@npm:~5.1.2": version: 5.1.2 resolution: "glob-parent@npm:5.1.2" dependencies: @@ -9149,13 +9892,6 @@ __metadata: languageName: node linkType: hard -"glob-to-regexp@npm:^0.3.0": - version: 0.3.0 - resolution: "glob-to-regexp@npm:0.3.0" - checksum: d34b3219d860042d508c4893b67617cd16e2668827e445ff39cff9f72ef70361d3dc24f429e003cdfb6607c75c9664b8eadc41d2eeb95690af0b0d3113c1b23b - languageName: node - linkType: hard - "glob@npm:^7.0.0, glob@npm:^7.0.3, glob@npm:^7.0.5, glob@npm:^7.1.1, glob@npm:^7.1.2, glob@npm:^7.1.3, glob@npm:^7.1.4, glob@npm:~7.1.1": version: 7.1.7 resolution: "glob@npm:7.1.7" @@ -9170,6 +9906,20 @@ __metadata: languageName: node linkType: hard +"glob@npm:^7.1.6": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: ^1.0.0 + inflight: ^1.0.4 + inherits: 2 + minimatch: ^3.1.1 + once: ^1.3.0 + path-is-absolute: ^1.0.0 + checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133 + languageName: node + linkType: hard + "glob@npm:^8.0.1": version: 8.1.0 resolution: "glob@npm:8.1.0" @@ -9219,27 +9969,35 @@ __metadata: languageName: node linkType: hard -"globals@npm:^12.1.0": - version: 12.4.0 - resolution: "globals@npm:12.4.0" +"globals@npm:^13.6.0, globals@npm:^13.9.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" dependencies: - type-fest: ^0.8.1 - checksum: 7ae5ee16a96f1e8d71065405f57da0e33267f6b070cd36a5444c7780dd28639b48b92413698ac64f04bf31594f9108878bd8cb158ecdf759c39e05634fefcca6 + type-fest: ^0.20.2 + checksum: 56066ef058f6867c04ff203b8a44c15b038346a62efbc3060052a1016be9f56f4cf0b2cd45b74b22b81e521a889fc7786c73691b0549c2f3a6e825b3d394f43c languageName: node linkType: hard -"globby@npm:8.0.2": - version: 8.0.2 - resolution: "globby@npm:8.0.2" +"globalthis@npm:^1.0.3": + version: 1.0.3 + resolution: "globalthis@npm:1.0.3" dependencies: - array-union: ^1.0.1 - dir-glob: 2.0.0 - fast-glob: ^2.0.2 - glob: ^7.1.2 - ignore: ^3.3.5 - pify: ^3.0.0 - slash: ^1.0.0 - checksum: 87dc31e0b812d3a6beee200555c252591d23ef12f8347bce3b61fa185a99fbe7ae1694ed30cc01a353e27369d6a8e1e50a97f1c5e2547fa7b1d87d8392ff9264 + define-properties: ^1.1.3 + checksum: fbd7d760dc464c886d0196166d92e5ffb4c84d0730846d6621a39fbbc068aeeb9c8d1421ad330e94b7bca4bb4ea092f5f21f3d36077812af5d098b4dc006c998 + languageName: node + linkType: hard + +"globby@npm:11.0.1": + version: 11.0.1 + resolution: "globby@npm:11.0.1" + dependencies: + array-union: ^2.1.0 + dir-glob: ^3.0.1 + fast-glob: ^3.1.1 + ignore: ^5.1.4 + merge2: ^1.3.0 + slash: ^3.0.0 + checksum: b0b26e580666ef8caf0b0facd585c1da46eb971207ee9f8c7b690c1372d77602dd072f047f26c3ae1c293807fdf8fb6890d9291d37bc6d2602b1f07386f983e5 languageName: node linkType: hard @@ -9281,13 +10039,29 @@ __metadata: languageName: node linkType: hard -"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.2": +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: ^1.1.3 + checksum: a5ccfb8806e0917a94e0b3de2af2ea4979c1da920bc381667c260e00e7cafdbe844e2cb9c5bcfef4e5412e8bf73bab837285bc35c7ba73aaaf0134d4583393a6 + languageName: node + linkType: hard + +"graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.15, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0": version: 4.2.6 resolution: "graceful-fs@npm:4.2.6" checksum: 792e64aafda05a151289f83eaa16aff34ef259658cefd65393883d959409f5a2389b0ec9ebf28f3d21f1b0ddc8f594a1162ae9b18e2b507a6799a70706ec573d languageName: node linkType: hard +"graceful-fs@npm:^4.2.4": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: ac85f94da92d8eb6b7f5a8b20ce65e43d66761c55ce85ac96df6865308390da45a8d3f0296dd3a663de65d30ba497bd46c696cc1e248c72b13d6d567138a4fc7 + languageName: node + linkType: hard + "graceful-fs@npm:^4.2.6": version: 4.2.9 resolution: "graceful-fs@npm:4.2.9" @@ -9350,15 +10124,6 @@ __metadata: languageName: node linkType: hard -"has-ansi@npm:^2.0.0": - version: 2.0.0 - resolution: "has-ansi@npm:2.0.0" - dependencies: - ansi-regex: ^2.0.0 - checksum: 1b51daa0214440db171ff359d0a2d17bc20061164c57e76234f614c91dbd2a79ddd68dfc8ee73629366f7be45a6df5f2ea9de83f52e1ca24433f2cc78c35d8ec - languageName: node - linkType: hard - "has-bigints@npm:^1.0.1": version: 1.0.1 resolution: "has-bigints@npm:1.0.1" @@ -9366,6 +10131,13 @@ __metadata: languageName: node linkType: hard +"has-bigints@npm:^1.0.2": + version: 1.0.2 + resolution: "has-bigints@npm:1.0.2" + checksum: 390e31e7be7e5c6fe68b81babb73dfc35d413604d7ee5f56da101417027a4b4ce6a27e46eff97ad040c835b5d228676eae99a9b5c3bc0e23c8e81a49241ff45b + languageName: node + linkType: hard + "has-flag@npm:^3.0.0": version: 3.0.0 resolution: "has-flag@npm:3.0.0" @@ -9380,6 +10152,22 @@ __metadata: languageName: node linkType: hard +"has-property-descriptors@npm:^1.0.0, has-property-descriptors@npm:^1.0.2": + version: 1.0.2 + resolution: "has-property-descriptors@npm:1.0.2" + dependencies: + es-define-property: ^1.0.0 + checksum: fcbb246ea2838058be39887935231c6d5788babed499d0e9d0cc5737494c48aba4fe17ba1449e0d0fbbb1e36175442faa37f9c427ae357d6ccb1d895fbcd3de3 + languageName: node + linkType: hard + +"has-proto@npm:^1.0.1, has-proto@npm:^1.0.3": + version: 1.0.3 + resolution: "has-proto@npm:1.0.3" + checksum: fe7c3d50b33f50f3933a04413ed1f69441d21d2d2944f81036276d30635cad9279f6b43bc8f32036c31ebdfcf6e731150f46c1907ad90c669ffe9b066c3ba5c4 + languageName: node + linkType: hard + "has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2": version: 1.0.2 resolution: "has-symbols@npm:1.0.2" @@ -9387,6 +10175,22 @@ __metadata: languageName: node linkType: hard +"has-symbols@npm:^1.0.3": + version: 1.0.3 + resolution: "has-symbols@npm:1.0.3" + checksum: a054c40c631c0d5741a8285010a0777ea0c068f99ed43e5d6eb12972da223f8af553a455132fdb0801bdcfa0e0f443c0c03a68d8555aa529b3144b446c3f2410 + languageName: node + linkType: hard + +"has-tostringtag@npm:^1.0.0, has-tostringtag@npm:^1.0.2": + version: 1.0.2 + resolution: "has-tostringtag@npm:1.0.2" + dependencies: + has-symbols: ^1.0.3 + checksum: 999d60bb753ad714356b2c6c87b7fb74f32463b8426e159397da4bde5bca7e598ab1073f4d8d4deafac297f2eb311484cd177af242776bf05f0d11565680468d + languageName: node + linkType: hard + "has-unicode@npm:^2.0.1": version: 2.0.1 resolution: "has-unicode@npm:2.0.1" @@ -9473,6 +10277,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.0, hasown@npm:^2.0.1, hasown@npm:^2.0.2": + version: 2.0.2 + resolution: "hasown@npm:2.0.2" + dependencies: + function-bind: ^1.1.2 + checksum: e8516f776a15149ca6c6ed2ae3110c417a00b62260e222590e54aa367cbcd6ed99122020b37b7fbdf05748df57b265e70095d7bf35a47660587619b15ffb93db + languageName: node + linkType: hard + "he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -9537,6 +10350,13 @@ __metadata: languageName: node linkType: hard +"hoopy@npm:^0.1.4": + version: 0.1.4 + resolution: "hoopy@npm:0.1.4" + checksum: cfa60c7684c5e1ee4efe26e167bc54b73f839ffb59d1d44a5c4bf891e26b4f5bcc666555219a98fec95508fea4eda3a79540c53c05cc79afc1f66f9a238f4d9e + languageName: node + linkType: hard + "hosted-git-info@npm:^2.1.4": version: 2.8.9 resolution: "hosted-git-info@npm:2.8.9" @@ -9589,16 +10409,16 @@ __metadata: languageName: node linkType: hard -"html-encoding-sniffer@npm:^1.0.2": - version: 1.0.2 - resolution: "html-encoding-sniffer@npm:1.0.2" +"html-encoding-sniffer@npm:^2.0.1": + version: 2.0.1 + resolution: "html-encoding-sniffer@npm:2.0.1" dependencies: - whatwg-encoding: ^1.0.1 - checksum: b874df6750451b7642fbe8e998c6bdd2911b0f42ad2927814b717bf1f4b082b0904b6178a1bfbc40117bf5799777993b0825e7713ca0fca49844e5aec03aa0e2 + whatwg-encoding: ^1.0.5 + checksum: bf30cce461015ed7e365736fcd6a3063c7bc016a91f74398ef6158886970a96333938f7c02417ab3c12aa82e3e53b40822145facccb9ddfbcdc15a879ae4d7ba languageName: node linkType: hard -"html-entities@npm:^1.3.1": +"html-entities@npm:^1.2.1, html-entities@npm:^1.3.1": version: 1.4.0 resolution: "html-entities@npm:1.4.0" checksum: 4b73ffb9eead200f99146e4fbe70acb0af2fea136901a131fc3a782e9ef876a7cbb07dec303ca1f8804232b812249dbf3643a270c9c524852065d9224a8dcdd0 @@ -9629,10 +10449,13 @@ __metadata: languageName: node linkType: hard -"html-webpack-plugin@npm:4.0.0-beta.11": - version: 4.0.0-beta.11 - resolution: "html-webpack-plugin@npm:4.0.0-beta.11" +"html-webpack-plugin@npm:4.5.0": + version: 4.5.0 + resolution: "html-webpack-plugin@npm:4.5.0" dependencies: + "@types/html-minifier-terser": ^5.0.0 + "@types/tapable": ^1.0.5 + "@types/webpack": ^4.41.8 html-minifier-terser: ^5.0.1 loader-utils: ^1.2.3 lodash: ^4.17.15 @@ -9640,8 +10463,8 @@ __metadata: tapable: ^1.1.3 util.promisify: 1.0.0 peerDependencies: - webpack: ^4.0.0 - checksum: ea34c7a12d20f938c59e6b5f404aaddac4689ec622995b748ce13e0016e52a199ff25a837b905dd756bebcfb35465435d4c455ed36e16bae3d3dc5e0706d0030 + webpack: ^4.0.0 || ^5.0.0 + checksum: d197db16a160ab9136a544e297c3c75d34b769d3cee12a82b9e7af7ee38ff07f4a27f2235581a9624f03996cd24997613df807341799140b4427c12bc4f496f9 languageName: node linkType: hard @@ -9810,7 +10633,7 @@ __metadata: languageName: node linkType: hard -"iconv-lite@npm:0.4.24, iconv-lite@npm:^0.4.24": +"iconv-lite@npm:0.4.24": version: 0.4.24 resolution: "iconv-lite@npm:0.4.24" dependencies: @@ -9860,13 +10683,6 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^3.3.5": - version: 3.3.10 - resolution: "ignore@npm:3.3.10" - checksum: 23e8cc776e367b56615ab21b78decf973a35dfca5522b39d9b47643d8168473b0d1f18dd1321a1bab466a12ea11a2411903f3b21644f4d5461ee0711ec8678bd - languageName: node - linkType: hard - "ignore@npm:^4.0.6": version: 4.0.6 resolution: "ignore@npm:4.0.6" @@ -9874,10 +10690,10 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0": - version: 5.2.4 - resolution: "ignore@npm:5.2.4" - checksum: 3d4c309c6006e2621659311783eaea7ebcd41fe4ca1d78c91c473157ad6666a57a2df790fe0d07a12300d9aac2888204d7be8d59f9aaf665b1c7fcdb432517ef +"ignore@npm:^5.1.4, ignore@npm:^5.1.8, ignore@npm:^5.2.0": + version: 5.3.1 + resolution: "ignore@npm:5.3.1" + checksum: 71d7bb4c1dbe020f915fd881108cbe85a0db3d636a0ea3ba911393c53946711d13a9b1143c7e70db06d571a5822c0a324a6bcde5c9904e7ca5047f01f1bf8cd3 languageName: node linkType: hard @@ -9895,10 +10711,10 @@ __metadata: languageName: node linkType: hard -"immer@npm:1.10.0": - version: 1.10.0 - resolution: "immer@npm:1.10.0" - checksum: 8bdce9ebd81861dcef21725bc0f9cc456c2051188b7c001bcd9b9dffb9519cd897ab207f475b5425b83767a4b1fba76b4665e3f3c41171e24ea938c3cd02d035 +"immer@npm:8.0.1": + version: 8.0.1 + resolution: "immer@npm:8.0.1" + checksum: 63d875c04882b862481a0a692816e5982975a47a57619698bc1bb52963ad3b624911991708b2b81a7af6fdac15083d408e43932d83a6a61216e5a4503efd4095 languageName: node linkType: hard @@ -9935,7 +10751,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.1.0": +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" dependencies: @@ -9966,6 +10782,18 @@ __metadata: languageName: node linkType: hard +"import-local@npm:^3.0.2": + version: 3.1.0 + resolution: "import-local@npm:3.1.0" + dependencies: + pkg-dir: ^4.2.0 + resolve-cwd: ^3.0.0 + bin: + import-local-fixture: fixtures/cli.js + checksum: bfcdb63b5e3c0e245e347f3107564035b128a414c4da1172a20dc67db2504e05ede4ac2eee1252359f78b0bfd7b19ef180aec427c2fce6493ae782d73a04cddd + languageName: node + linkType: hard + "imurmurhash@npm:^0.1.4": version: 0.1.4 resolution: "imurmurhash@npm:0.1.4" @@ -9982,15 +10810,6 @@ __metadata: languageName: node linkType: hard -"indent-string@npm:^2.1.0": - version: 2.1.0 - resolution: "indent-string@npm:2.1.0" - dependencies: - repeating: ^2.0.0 - checksum: 2fe7124311435f4d7a98f0a314d8259a4ec47ecb221110a58e2e2073e5f75c8d2b4f775f2ed199598fbe20638917e57423096539455ca8bff8eab113c9bee12c - languageName: node - linkType: hard - "indent-string@npm:^4.0.0": version: 4.0.0 resolution: "indent-string@npm:4.0.0" @@ -10057,48 +10876,6 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:7.0.4": - version: 7.0.4 - resolution: "inquirer@npm:7.0.4" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^2.4.2 - cli-cursor: ^3.1.0 - cli-width: ^2.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.15 - mute-stream: 0.0.8 - run-async: ^2.2.0 - rxjs: ^6.5.3 - string-width: ^4.1.0 - strip-ansi: ^5.1.0 - through: ^2.3.6 - checksum: 01a87cdbe74e7eb5ca770580f0d6bcad0269e6b0da97107aa9e2b37446a795aac63a63865d33410e964441499f9ac34a84c2e97c40d1abe2e57efc7f0d5b416d - languageName: node - linkType: hard - -"inquirer@npm:^7.0.0": - version: 7.3.3 - resolution: "inquirer@npm:7.3.3" - dependencies: - ansi-escapes: ^4.2.1 - chalk: ^4.1.0 - cli-cursor: ^3.1.0 - cli-width: ^3.0.0 - external-editor: ^3.0.3 - figures: ^3.0.0 - lodash: ^4.17.19 - mute-stream: 0.0.8 - run-async: ^2.4.0 - rxjs: ^6.6.0 - string-width: ^4.1.0 - strip-ansi: ^6.0.0 - through: ^2.3.6 - checksum: 4d387fc1eb6126acbd58cbdb9ad99d2887d181df86ab0c2b9abdf734e751093e2d5882c2b6dc7144d9ab16b7ab30a78a1d7f01fb6a2850a44aeb175d1e3f8778 - languageName: node - linkType: hard - "internal-ip@npm:^4.3.0": version: 4.3.0 resolution: "internal-ip@npm:4.3.0" @@ -10109,18 +10886,18 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.3": - version: 1.0.3 - resolution: "internal-slot@npm:1.0.3" +"internal-slot@npm:^1.0.7": + version: 1.0.7 + resolution: "internal-slot@npm:1.0.7" dependencies: - get-intrinsic: ^1.1.0 - has: ^1.0.3 + es-errors: ^1.3.0 + hasown: ^2.0.0 side-channel: ^1.0.4 - checksum: 1944f92e981e47aebc98a88ff0db579fd90543d937806104d0b96557b10c1f170c51fb777b97740a8b6ddeec585fca8c39ae99fd08a8e058dfc8ab70937238bf + checksum: cadc5eea5d7d9bc2342e93aae9f31f04c196afebb11bde97448327049f492cd7081e18623ae71388aac9cd237b692ca3a105be9c68ac39c1dec679d7409e33eb languageName: node linkType: hard -"invariant@npm:^2.0.0, invariant@npm:^2.1.0, invariant@npm:^2.2.2, invariant@npm:^2.2.4": +"invariant@npm:^2.0.0, invariant@npm:^2.1.0, invariant@npm:^2.2.4": version: 2.2.4 resolution: "invariant@npm:2.2.4" dependencies: @@ -10129,13 +10906,6 @@ __metadata: languageName: node linkType: hard -"invert-kv@npm:^1.0.0": - version: 1.0.0 - resolution: "invert-kv@npm:1.0.0" - checksum: aebeee31dda3b3d25ffd242e9a050926e7fe5df642d60953ab183aca1a7d1ffb39922eb2618affb0e850cf2923116f0da1345367759d88d097df5da1f1e1590e - languageName: node - linkType: hard - "ip-regex@npm:^2.1.0": version: 2.1.0 resolution: "ip-regex@npm:2.1.0" @@ -10205,6 +10975,16 @@ __metadata: languageName: node linkType: hard +"is-array-buffer@npm:^3.0.4": + version: 3.0.4 + resolution: "is-array-buffer@npm:3.0.4" + dependencies: + call-bind: ^1.0.2 + get-intrinsic: ^1.2.1 + checksum: e4e3e6ef0ff2239e75371d221f74bc3c26a03564a22efb39f6bb02609b598917ddeecef4e8c877df2a25888f247a98198959842a5e73236bc7f22cabdf6351a7 + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -10219,6 +10999,15 @@ __metadata: languageName: node linkType: hard +"is-async-function@npm:^2.0.0": + version: 2.0.0 + resolution: "is-async-function@npm:2.0.0" + dependencies: + has-tostringtag: ^1.0.0 + checksum: e3471d95e6c014bf37cad8a93f2f4b6aac962178e0a5041e8903147166964fdc1c5c1d2ef87e86d77322c370ca18f2ea004fa7420581fa747bcaf7c223069dbd + languageName: node + linkType: hard + "is-bigint@npm:^1.0.1": version: 1.0.2 resolution: "is-bigint@npm:1.0.2" @@ -10253,7 +11042,7 @@ __metadata: languageName: node linkType: hard -"is-buffer@npm:^1.0.2, is-buffer@npm:^1.1.5": +"is-buffer@npm:^1.1.5": version: 1.1.6 resolution: "is-buffer@npm:1.1.6" checksum: 4a186d995d8bbf9153b4bd9ff9fd04ae75068fe695d29025d25e592d9488911eeece84eefbd8fa41b8ddcc0711058a71d4c466dcf6f1f6e1d83830052d8ca707 @@ -10267,6 +11056,13 @@ __metadata: languageName: node linkType: hard +"is-callable@npm:^1.2.7": + version: 1.2.7 + resolution: "is-callable@npm:1.2.7" + checksum: 61fd57d03b0d984e2ed3720fb1c7a897827ea174bd44402878e059542ea8c4aeedee0ea0985998aa5cc2736b2fa6e271c08587addb5b3959ac52cf665173d1ac + languageName: node + linkType: hard + "is-ci@npm:^2.0.0": version: 2.0.0 resolution: "is-ci@npm:2.0.0" @@ -10303,6 +11099,15 @@ __metadata: languageName: node linkType: hard +"is-core-module@npm:^2.0.0, is-core-module@npm:^2.13.0, is-core-module@npm:^2.13.1": + version: 2.13.1 + resolution: "is-core-module@npm:2.13.1" + dependencies: + hasown: ^2.0.0 + checksum: 256559ee8a9488af90e4bad16f5583c6d59e92f0742e9e8bb4331e758521ee86b810b93bae44f390766ffbc518a0488b18d9dab7da9a5ff997d499efc9403f7c + languageName: node + linkType: hard + "is-core-module@npm:^2.2.0": version: 2.4.0 resolution: "is-core-module@npm:2.4.0" @@ -10339,6 +11144,15 @@ __metadata: languageName: node linkType: hard +"is-data-view@npm:^1.0.1": + version: 1.0.1 + resolution: "is-data-view@npm:1.0.1" + dependencies: + is-typed-array: ^1.1.13 + checksum: 4ba4562ac2b2ec005fefe48269d6bd0152785458cd253c746154ffb8a8ab506a29d0cfb3b74af87513843776a88e4981ae25c89457bf640a33748eab1a7216b5 + languageName: node + linkType: hard + "is-date-object@npm:^1.0.1": version: 1.0.4 resolution: "is-date-object@npm:1.0.4" @@ -10346,6 +11160,15 @@ __metadata: languageName: node linkType: hard +"is-date-object@npm:^1.0.5": + version: 1.0.5 + resolution: "is-date-object@npm:1.0.5" + dependencies: + has-tostringtag: ^1.0.0 + checksum: baa9077cdf15eb7b58c79398604ca57379b2fc4cf9aa7a9b9e295278648f628c9b201400c01c5e0f7afae56507d741185730307cbe7cad3b9f90a77e5ee342fc + languageName: node + linkType: hard + "is-descriptor@npm:^0.1.0": version: 0.1.6 resolution: "is-descriptor@npm:0.1.6" @@ -10407,19 +11230,12 @@ __metadata: languageName: node linkType: hard -"is-finite@npm:^1.0.0": - version: 1.1.0 - resolution: "is-finite@npm:1.1.0" - checksum: 532b97ed3d03e04c6bd203984d9e4ba3c0c390efee492bad5d1d1cd1802a68ab27adbd3ef6382f6312bed6c8bb1bd3e325ea79a8dc8fe080ed7a06f5f97b93e7 - languageName: node - linkType: hard - -"is-fullwidth-code-point@npm:^1.0.0": - version: 1.0.0 - resolution: "is-fullwidth-code-point@npm:1.0.0" +"is-finalizationregistry@npm:^1.0.2": + version: 1.0.2 + resolution: "is-finalizationregistry@npm:1.0.2" dependencies: - number-is-nan: ^1.0.0 - checksum: 4d46a7465a66a8aebcc5340d3b63a56602133874af576a9ca42c6f0f4bd787a743605771c5f246db77da96605fefeffb65fc1dbe862dcc7328f4b4d03edf5a57 + call-bind: ^1.0.2 + checksum: 4f243a8e06228cd45bdab8608d2cb7abfc20f6f0189c8ac21ea8d603f1f196eabd531ce0bb8e08cbab047e9845ef2c191a3761c9a17ad5cabf8b35499c4ad35d languageName: node linkType: hard @@ -10444,6 +11260,15 @@ __metadata: languageName: node linkType: hard +"is-generator-function@npm:^1.0.10": + version: 1.0.10 + resolution: "is-generator-function@npm:1.0.10" + dependencies: + has-tostringtag: ^1.0.0 + checksum: d54644e7dbaccef15ceb1e5d91d680eb5068c9ee9f9eb0a9e04173eb5542c9b51b5ab52c5537f5703e48d5fddfd376817c1ca07a84a407b7115b769d4bdde72b + languageName: node + linkType: hard + "is-glob@npm:^3.1.0": version: 3.1.0 resolution: "is-glob@npm:3.1.0" @@ -10462,6 +11287,15 @@ __metadata: languageName: node linkType: hard +"is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: ^2.1.1 + checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 + languageName: node + linkType: hard + "is-image@npm:*, is-image@npm:3.0.0": version: 3.0.0 resolution: "is-image@npm:3.0.0" @@ -10495,6 +11329,20 @@ __metadata: languageName: node linkType: hard +"is-map@npm:^2.0.3": + version: 2.0.3 + resolution: "is-map@npm:2.0.3" + checksum: e6ce5f6380f32b141b3153e6ba9074892bbbbd655e92e7ba5ff195239777e767a976dcd4e22f864accaf30e53ebf961ab1995424aef91af68788f0591b7396cc + languageName: node + linkType: hard + +"is-module@npm:^1.0.0": + version: 1.0.0 + resolution: "is-module@npm:1.0.0" + checksum: 8cd5390730c7976fb4e8546dd0b38865ee6f7bacfa08dfbb2cc07219606755f0b01709d9361e01f13009bbbd8099fa2927a8ed665118a6105d66e40f1b838c3f + languageName: node + linkType: hard + "is-negative-zero@npm:^2.0.1": version: 2.0.1 resolution: "is-negative-zero@npm:2.0.1" @@ -10502,6 +11350,13 @@ __metadata: languageName: node linkType: hard +"is-negative-zero@npm:^2.0.3": + version: 2.0.3 + resolution: "is-negative-zero@npm:2.0.3" + checksum: c1e6b23d2070c0539d7b36022d5a94407132411d01aba39ec549af824231f3804b1aea90b5e4e58e807a65d23ceb538ed6e355ce76b267bdd86edb757ffcbdcd + languageName: node + linkType: hard + "is-number-object@npm:^1.0.4": version: 1.0.5 resolution: "is-number-object@npm:1.0.5" @@ -10578,7 +11433,7 @@ __metadata: languageName: node linkType: hard -"is-plain-object@npm:^2.0.1, is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": +"is-plain-object@npm:^2.0.3, is-plain-object@npm:^2.0.4": version: 2.0.4 resolution: "is-plain-object@npm:2.0.4" dependencies: @@ -10587,6 +11442,13 @@ __metadata: languageName: node linkType: hard +"is-potential-custom-element-name@npm:^1.0.1": + version: 1.0.1 + resolution: "is-potential-custom-element-name@npm:1.0.1" + checksum: ced7bbbb6433a5b684af581872afe0e1767e2d1146b2207ca0068a648fb5cab9d898495d1ac0583524faaf24ca98176a7d9876363097c2d14fee6dd324f3a1ab + languageName: node + linkType: hard + "is-promise@npm:^2.1.0": version: 2.2.2 resolution: "is-promise@npm:2.2.2" @@ -10604,6 +11466,16 @@ __metadata: languageName: node linkType: hard +"is-regex@npm:^1.1.4": + version: 1.1.4 + resolution: "is-regex@npm:1.1.4" + dependencies: + call-bind: ^1.0.2 + has-tostringtag: ^1.0.0 + checksum: 362399b33535bc8f386d96c45c9feb04cf7f8b41c182f54174c1a45c9abbbe5e31290bbad09a458583ff6bf3b2048672cdb1881b13289569a7c548370856a652 + languageName: node + linkType: hard + "is-regexp@npm:^1.0.0": version: 1.0.0 resolution: "is-regexp@npm:1.0.0" @@ -10625,6 +11497,22 @@ __metadata: languageName: node linkType: hard +"is-set@npm:^2.0.3": + version: 2.0.3 + resolution: "is-set@npm:2.0.3" + checksum: 36e3f8c44bdbe9496c9689762cc4110f6a6a12b767c5d74c0398176aa2678d4467e3bf07595556f2dba897751bde1422480212b97d973c7b08a343100b0c0dfe + languageName: node + linkType: hard + +"is-shared-array-buffer@npm:^1.0.2, is-shared-array-buffer@npm:^1.0.3": + version: 1.0.3 + resolution: "is-shared-array-buffer@npm:1.0.3" + dependencies: + call-bind: ^1.0.7 + checksum: a4fff602c309e64ccaa83b859255a43bb011145a42d3f56f67d9268b55bc7e6d98a5981a1d834186ad3105d6739d21547083fe7259c76c0468483fc538e716d8 + languageName: node + linkType: hard + "is-stream@npm:^1.0.1, is-stream@npm:^1.1.0": version: 1.1.0 resolution: "is-stream@npm:1.1.0" @@ -10646,6 +11534,15 @@ __metadata: languageName: node linkType: hard +"is-string@npm:^1.0.7": + version: 1.0.7 + resolution: "is-string@npm:1.0.7" + dependencies: + has-tostringtag: ^1.0.0 + checksum: 323b3d04622f78d45077cf89aab783b2f49d24dc641aa89b5ad1a72114cfeff2585efc8c12ef42466dff32bde93d839ad321b26884cf75e5a7892a938b089989 + languageName: node + linkType: hard + "is-subset@npm:^0.1.1": version: 0.1.1 resolution: "is-subset@npm:0.1.1" @@ -10662,7 +11559,16 @@ __metadata: languageName: node linkType: hard -"is-typedarray@npm:~1.0.0": +"is-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "is-typed-array@npm:1.1.13" + dependencies: + which-typed-array: ^1.1.14 + checksum: 150f9ada183a61554c91e1c4290086d2c100b0dff45f60b028519be72a8db964da403c48760723bf5253979b8dffe7b544246e0e5351dcd05c5fdb1dcc1dc0f0 + languageName: node + linkType: hard + +"is-typedarray@npm:^1.0.0, is-typedarray@npm:~1.0.0": version: 1.0.0 resolution: "is-typedarray@npm:1.0.0" checksum: 3508c6cd0a9ee2e0df2fa2e9baabcdc89e911c7bd5cf64604586697212feec525aa21050e48affb5ffc3df20f0f5d2e2cf79b08caa64e1ccc9578e251763aef7 @@ -10676,10 +11582,29 @@ __metadata: languageName: node linkType: hard -"is-utf8@npm:^0.2.0": - version: 0.2.1 - resolution: "is-utf8@npm:0.2.1" - checksum: 167ccd2be869fc228cc62c1a28df4b78c6b5485d15a29027d3b5dceb09b383e86a3522008b56dcac14b592b22f0a224388718c2505027a994fd8471465de54b3 +"is-weakmap@npm:^2.0.2": + version: 2.0.2 + resolution: "is-weakmap@npm:2.0.2" + checksum: f36aef758b46990e0d3c37269619c0a08c5b29428c0bb11ecba7f75203442d6c7801239c2f31314bc79199217ef08263787f3837d9e22610ad1da62970d6616d + languageName: node + linkType: hard + +"is-weakref@npm:^1.0.2": + version: 1.0.2 + resolution: "is-weakref@npm:1.0.2" + dependencies: + call-bind: ^1.0.2 + checksum: 95bd9a57cdcb58c63b1c401c60a474b0f45b94719c30f548c891860f051bc2231575c290a6b420c6bc6e7ed99459d424c652bd5bf9a1d5259505dc35b4bf83de + languageName: node + linkType: hard + +"is-weakset@npm:^2.0.3": + version: 2.0.3 + resolution: "is-weakset@npm:2.0.3" + dependencies: + call-bind: ^1.0.7 + get-intrinsic: ^1.2.4 + checksum: 8b6a20ee9f844613ff8f10962cfee49d981d584525f2357fee0a04dfbcde9fd607ed60cb6dab626dbcc470018ae6392e1ff74c0c1aced2d487271411ad9d85ae languageName: node linkType: hard @@ -10697,7 +11622,7 @@ __metadata: languageName: node linkType: hard -"is-wsl@npm:^2.1.1": +"is-wsl@npm:^2.1.1, is-wsl@npm:^2.2.0": version: 2.2.0 resolution: "is-wsl@npm:2.2.0" dependencies: @@ -10720,6 +11645,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: bd5bbe4104438c4196ba58a54650116007fa0262eccef13a4c55b2e09a5b36b59f1e75b9fcc49883dd9d4953892e6fc007eef9e9155648ceea036e184b0f930a + languageName: node + linkType: hard + "isexe@npm:^2.0.0": version: 2.0.0 resolution: "isexe@npm:2.0.0" @@ -10760,133 +11692,178 @@ __metadata: languageName: node linkType: hard -"istanbul-lib-coverage@npm:^2.0.2, istanbul-lib-coverage@npm:^2.0.5": - version: 2.0.5 - resolution: "istanbul-lib-coverage@npm:2.0.5" - checksum: c83bf39dc722d2a3e7c98b16643f2fef719fd59adf23441ad8a1e6422bb1f3367ac7d4c42ac45d0d87413476891947b6ffbdecf2184047436336aa0c28bbfc15 +"istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": + version: 3.2.2 + resolution: "istanbul-lib-coverage@npm:3.2.2" + checksum: 2367407a8d13982d8f7a859a35e7f8dd5d8f75aae4bb5484ede3a9ea1b426dc245aff28b976a2af48ee759fdd9be374ce2bd2669b644f31e76c5f46a2e29a831 languageName: node linkType: hard -"istanbul-lib-instrument@npm:^3.0.1, istanbul-lib-instrument@npm:^3.3.0": - version: 3.3.0 - resolution: "istanbul-lib-instrument@npm:3.3.0" - dependencies: - "@babel/generator": ^7.4.0 - "@babel/parser": ^7.4.3 - "@babel/template": ^7.4.0 - "@babel/traverse": ^7.4.3 - "@babel/types": ^7.4.0 - istanbul-lib-coverage: ^2.0.5 - semver: ^6.0.0 - checksum: 5ff86440c2f4afe83603f899721e43f9bbc0049ebf4e7fd696ea361d0c9ae5c831c656eec07c13f42ba934fc808c78f42a7884f1a08349802bc9bfa5af760571 +"istanbul-lib-instrument@npm:^4.0.3": + version: 4.0.3 + resolution: "istanbul-lib-instrument@npm:4.0.3" + dependencies: + "@babel/core": ^7.7.5 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-coverage: ^3.0.0 + semver: ^6.3.0 + checksum: fa1171d3022b1bb8f6a734042620ac5d9ee7dc80f3065a0bb12863e9f0494d0eefa3d86608fcc0254ab2765d29d7dad8bdc42e5f8df2f9a1fbe85ccc59d76cb9 languageName: node linkType: hard -"istanbul-lib-report@npm:^2.0.4": - version: 2.0.8 - resolution: "istanbul-lib-report@npm:2.0.8" +"istanbul-lib-instrument@npm:^5.0.4": + version: 5.2.1 + resolution: "istanbul-lib-instrument@npm:5.2.1" dependencies: - istanbul-lib-coverage: ^2.0.5 - make-dir: ^2.1.0 - supports-color: ^6.1.0 - checksum: eef53d35ea750fd971bc7abf2cf1350615804e4dee5a7ee6e13cff45ff36b518970baaeef4bf019d46149581f9d10c3f3675083cf6625da6cc3d4d4b4c670374 + "@babel/core": ^7.12.3 + "@babel/parser": ^7.14.7 + "@istanbuljs/schema": ^0.1.2 + istanbul-lib-coverage: ^3.2.0 + semver: ^6.3.0 + checksum: bf16f1803ba5e51b28bbd49ed955a736488381e09375d830e42ddeb403855b2006f850711d95ad726f2ba3f1ae8e7366de7e51d2b9ac67dc4d80191ef7ddf272 languageName: node linkType: hard -"istanbul-lib-source-maps@npm:^3.0.1": - version: 3.0.6 - resolution: "istanbul-lib-source-maps@npm:3.0.6" +"istanbul-lib-report@npm:^3.0.0": + version: 3.0.1 + resolution: "istanbul-lib-report@npm:3.0.1" + dependencies: + istanbul-lib-coverage: ^3.0.0 + make-dir: ^4.0.0 + supports-color: ^7.1.0 + checksum: fd17a1b879e7faf9bb1dc8f80b2a16e9f5b7b8498fe6ed580a618c34df0bfe53d2abd35bf8a0a00e628fb7405462576427c7df20bbe4148d19c14b431c974b21 + languageName: node + linkType: hard + +"istanbul-lib-source-maps@npm:^4.0.0": + version: 4.0.1 + resolution: "istanbul-lib-source-maps@npm:4.0.1" dependencies: debug: ^4.1.1 - istanbul-lib-coverage: ^2.0.5 - make-dir: ^2.1.0 - rimraf: ^2.6.3 + istanbul-lib-coverage: ^3.0.0 source-map: ^0.6.1 - checksum: 1c6ebc81331ab4d831910db3e98da1ee4e3e96f64c2fb533e1b73516305f020b44765fa2937f24eee4adb11be22a1fa42c04786e0d697d4893987a1a5180a541 + checksum: 21ad3df45db4b81852b662b8d4161f6446cd250c1ddc70ef96a585e2e85c26ed7cd9c2a396a71533cfb981d1a645508bc9618cae431e55d01a0628e7dec62ef2 languageName: node linkType: hard -"istanbul-reports@npm:^2.2.6": - version: 2.2.7 - resolution: "istanbul-reports@npm:2.2.7" +"istanbul-reports@npm:^3.0.2": + version: 3.1.7 + resolution: "istanbul-reports@npm:3.1.7" dependencies: html-escaper: ^2.0.0 - checksum: 138604c86fe4a386c4ba23c103aa64f3d867548cb1ac9961cafe912004bde601180d7ece918a76e2e0078b94e503b77aa696d6e6f68a0d8698abbf0923d78285 + istanbul-lib-report: ^3.0.0 + checksum: 2072db6e07bfbb4d0eb30e2700250636182398c1af811aea5032acb219d2080f7586923c09fa194029efd6b92361afb3dcbe1ebcc3ee6651d13340f7c6c4ed95 languageName: node linkType: hard -"jest-changed-files@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-changed-files@npm:24.9.0" +"iterator.prototype@npm:^1.1.2": + version: 1.1.2 + resolution: "iterator.prototype@npm:1.1.2" dependencies: - "@jest/types": ^24.9.0 - execa: ^1.0.0 - throat: ^4.0.0 - checksum: f40e901e6ac2e6f47730b610c3dbef44a9235d556ba53b23926d45e6334c1c5989fd255140753d3270d5e63371ae69084e0867c11b8322030edab51e1ff1b8b7 + define-properties: ^1.2.1 + get-intrinsic: ^1.2.1 + has-symbols: ^1.0.3 + reflect.getprototypeof: ^1.0.4 + set-function-name: ^2.0.1 + checksum: d8a507e2ccdc2ce762e8a1d3f4438c5669160ac72b88b648e59a688eec6bc4e64b22338e74000518418d9e693faf2a092d2af21b9ec7dbf7763b037a54701168 languageName: node linkType: hard -"jest-cli@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-cli@npm:24.9.0" +"jest-changed-files@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-changed-files@npm:26.6.2" + dependencies: + "@jest/types": ^26.6.2 + execa: ^4.0.0 + throat: ^5.0.0 + checksum: 8c405f5ff905ee69ace9fd39355233206e3e233badf6a3f3b27e45bbf0a46d86943430be2e080d25b1e085f4231b9b3b27c94317aa04116efb40b592184066f4 + languageName: node + linkType: hard + +"jest-circus@npm:26.6.0": + version: 26.6.0 + resolution: "jest-circus@npm:26.6.0" dependencies: - "@jest/core": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - chalk: ^2.0.1 + "@babel/traverse": ^7.1.0 + "@jest/environment": ^26.6.0 + "@jest/test-result": ^26.6.0 + "@jest/types": ^26.6.0 + "@types/babel__traverse": ^7.0.4 + "@types/node": "*" + chalk: ^4.0.0 + co: ^4.6.0 + dedent: ^0.7.0 + expect: ^26.6.0 + is-generator-fn: ^2.0.0 + jest-each: ^26.6.0 + jest-matcher-utils: ^26.6.0 + jest-message-util: ^26.6.0 + jest-runner: ^26.6.0 + jest-runtime: ^26.6.0 + jest-snapshot: ^26.6.0 + jest-util: ^26.6.0 + pretty-format: ^26.6.0 + stack-utils: ^2.0.2 + throat: ^5.0.0 + checksum: acc354223964bafd40fd1caae4099b58ccb1551bc93a394398b441274c225552f1941ce9903d126fb0adc3952a108e2994270c6a50a3e7e5af931b65b8c170f0 + languageName: node + linkType: hard + +"jest-cli@npm:^26.6.0": + version: 26.6.3 + resolution: "jest-cli@npm:26.6.3" + dependencies: + "@jest/core": ^26.6.3 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 + chalk: ^4.0.0 exit: ^0.1.2 - import-local: ^2.0.0 + graceful-fs: ^4.2.4 + import-local: ^3.0.2 is-ci: ^2.0.0 - jest-config: ^24.9.0 - jest-util: ^24.9.0 - jest-validate: ^24.9.0 + jest-config: ^26.6.3 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 prompts: ^2.0.1 - realpath-native: ^1.1.0 - yargs: ^13.3.0 + yargs: ^15.4.1 bin: - jest: ./bin/jest.js - checksum: 8fc975da02e6793352a3508fae1523c094ed44633dc5e651aa1f01e49b9d4be8353422fd5dc7f01e464f6aafee13b3210daf3d11ce466c8959071251bdb0dc09 + jest: bin/jest.js + checksum: c8554147be756f09f5566974f0026485f78742e8642d2723f8fbee5746f50f44fb72b17aad181226655a8446d3ecc8ad8ed0a11a8a55686fa2b9c10d85700121 languageName: node linkType: hard -"jest-config@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-config@npm:24.9.0" +"jest-config@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-config@npm:26.6.3" dependencies: "@babel/core": ^7.1.0 - "@jest/test-sequencer": ^24.9.0 - "@jest/types": ^24.9.0 - babel-jest: ^24.9.0 - chalk: ^2.0.1 + "@jest/test-sequencer": ^26.6.3 + "@jest/types": ^26.6.2 + babel-jest: ^26.6.3 + chalk: ^4.0.0 + deepmerge: ^4.2.2 glob: ^7.1.1 - jest-environment-jsdom: ^24.9.0 - jest-environment-node: ^24.9.0 - jest-get-type: ^24.9.0 - jest-jasmine2: ^24.9.0 - jest-regex-util: ^24.3.0 - jest-resolve: ^24.9.0 - jest-util: ^24.9.0 - jest-validate: ^24.9.0 - micromatch: ^3.1.10 - pretty-format: ^24.9.0 - realpath-native: ^1.1.0 - checksum: 87268fcab5322775601181f4ee17d51102ba153b1e0dc68a55075e44109b372f4925fe9c361cca6a72d5934f806b16f8331f0efad8b6b296a6f7bffcb7a34cb9 - languageName: node - linkType: hard - -"jest-diff@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-diff@npm:24.9.0" - dependencies: - chalk: ^2.0.1 - diff-sequences: ^24.9.0 - jest-get-type: ^24.9.0 - pretty-format: ^24.9.0 - checksum: 462ccb128cb1b64eb285d28245d0c5bfc230cb063624bd117550d6dbc94332f606828a5de86938611d1e6a78489e576c496737ae139084f6049a56b768ad6402 + graceful-fs: ^4.2.4 + jest-environment-jsdom: ^26.6.2 + jest-environment-node: ^26.6.2 + jest-get-type: ^26.3.0 + jest-jasmine2: ^26.6.3 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 + micromatch: ^4.0.2 + pretty-format: ^26.6.2 + peerDependencies: + ts-node: ">=9.0.0" + peerDependenciesMeta: + ts-node: + optional: true + checksum: 303c798582d3c5d4b4e6ab8a4d91a83ded28e4ebbc0bcfc1ad271f9864437ef5409b7c7773010143811bc8176b0695c096717b91419c6484b56dcc032560a74b languageName: node linkType: hard -"jest-diff@npm:^26.0.0": +"jest-diff@npm:^26.0.0, jest-diff@npm:^26.6.2": version: 26.6.2 resolution: "jest-diff@npm:26.6.2" dependencies: @@ -10898,73 +11875,54 @@ __metadata: languageName: node linkType: hard -"jest-docblock@npm:^24.3.0": - version: 24.9.0 - resolution: "jest-docblock@npm:24.9.0" - dependencies: - detect-newline: ^2.1.0 - checksum: 0b2321a4ac5b2b59f9183f805d4c50223635e53ce76080c406da3d499916972b70ce8809fda6d0616b2ce606dd201be36be6b4c8c62ae2c0e62f14cfa3bfcbdb - languageName: node - linkType: hard - -"jest-each@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-each@npm:24.9.0" +"jest-docblock@npm:^26.0.0": + version: 26.0.0 + resolution: "jest-docblock@npm:26.0.0" dependencies: - "@jest/types": ^24.9.0 - chalk: ^2.0.1 - jest-get-type: ^24.9.0 - jest-util: ^24.9.0 - pretty-format: ^24.9.0 - checksum: 93dc198e1dbea985816e3739b8a6e8622f1ee7b3f8b97d074aa8d512b4f81b8b70b30dcdcb5f735b3407bbd0fe5a9ac06e38cbf6499f7ab302daff2832c49683 + detect-newline: ^3.0.0 + checksum: e03ef104ee8c571335e6fa394b8fc8d2bd87eec9fe8b3d7d9aac056ada7de288f37ee8ac4922bb3a4222ac304db975d8832d5abc85486092866c534a16847cd5 languageName: node linkType: hard -"jest-environment-jsdom-fourteen@npm:1.0.1": - version: 1.0.1 - resolution: "jest-environment-jsdom-fourteen@npm:1.0.1" +"jest-each@npm:^26.6.0, jest-each@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-each@npm:26.6.2" dependencies: - "@jest/environment": ^24.3.0 - "@jest/fake-timers": ^24.3.0 - "@jest/types": ^24.3.0 - jest-mock: ^24.0.0 - jest-util: ^24.0.0 - jsdom: ^14.1.0 - checksum: 39b34962c44260b69a58bab74ba36c6746db70947e6a44695ea26776bda2a9d9fd66edd1f6c36e9f456e5e0993633339f0db86fc452e0f1dfcaa9336a0656a35 + "@jest/types": ^26.6.2 + chalk: ^4.0.0 + jest-get-type: ^26.3.0 + jest-util: ^26.6.2 + pretty-format: ^26.6.2 + checksum: 4e00ea4667e4fe015b894dc698cce0ae695cf458e021e5da62d4a5b052cd2c0a878da93f8c97cbdde60bcecf70982e8d3a7a5d63e1588f59531cc797a18c39ef languageName: node linkType: hard -"jest-environment-jsdom@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-environment-jsdom@npm:24.9.0" +"jest-environment-jsdom@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-environment-jsdom@npm:26.6.2" dependencies: - "@jest/environment": ^24.9.0 - "@jest/fake-timers": ^24.9.0 - "@jest/types": ^24.9.0 - jest-mock: ^24.9.0 - jest-util: ^24.9.0 - jsdom: ^11.5.1 - checksum: 093e7f25735e52a1ff01673f0e3921e3e8228d2e902762bf102f1c34cd206e9b73aa83dcd0598e101c6cf4c23e99e5c84df84084258268a696c3007d6990f701 + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + jsdom: ^16.4.0 + checksum: 8af9ffdf1b147362a19032bfe9ed51b709d43c74dc4b1c45e56d721808bf6cabdca8c226855b55a985ea196ce51cdb171bfe420ceec3daa2d13818d5c1915890 languageName: node linkType: hard -"jest-environment-node@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-environment-node@npm:24.9.0" +"jest-environment-node@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-environment-node@npm:26.6.2" dependencies: - "@jest/environment": ^24.9.0 - "@jest/fake-timers": ^24.9.0 - "@jest/types": ^24.9.0 - jest-mock: ^24.9.0 - jest-util: ^24.9.0 - checksum: 61a446f7cbab96b1777f53bcbb45ecda139a2473c7a093a9420f0018824ec307b93f920f9e188b5f11b605d0ed14798396c97113aedb66c2801b29367a5dc8d2 - languageName: node - linkType: hard - -"jest-get-type@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-get-type@npm:24.9.0" - checksum: 821e6cd46434c917370cd362fbc4ce564c6e22780351f3ca468b230fbbc657ae19905ed5cdcc5e112d81a2c79cbd3fbcbe0dd44dc62860414b60ea223009958c + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + jest-mock: ^26.6.2 + jest-util: ^26.6.2 + checksum: 0b69b481e6d6f2350ed241c2dabc70b0b1f3a00f9a410b7dad97c8ab38e88026acf7445ca663eb314f46ff50acee0133100b1006bf4ebda5298ffb02763a6861 languageName: node linkType: hard @@ -10975,60 +11933,64 @@ __metadata: languageName: node linkType: hard -"jest-haste-map@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-haste-map@npm:24.9.0" +"jest-haste-map@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-haste-map@npm:26.6.2" dependencies: - "@jest/types": ^24.9.0 - anymatch: ^2.0.0 + "@jest/types": ^26.6.2 + "@types/graceful-fs": ^4.1.2 + "@types/node": "*" + anymatch: ^3.0.3 fb-watchman: ^2.0.0 - fsevents: ^1.2.7 - graceful-fs: ^4.1.15 - invariant: ^2.2.4 - jest-serializer: ^24.9.0 - jest-util: ^24.9.0 - jest-worker: ^24.9.0 - micromatch: ^3.1.10 + fsevents: ^2.1.2 + graceful-fs: ^4.2.4 + jest-regex-util: ^26.0.0 + jest-serializer: ^26.6.2 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 + micromatch: ^4.0.2 sane: ^4.0.3 walker: ^1.0.7 dependenciesMeta: fsevents: optional: true - checksum: 3ec2d60863c315d52a32b2d1df3cc8bb5403f7d8bf159e556c878db09dedc4d1fb4e4d5f56cb67c92663b334d49ef8b768375b0d153adebf4d48a7b6959e71b3 + checksum: 8ad5236d5646d2388d2bd58a57ea53698923434f43d59ea9ebdc58bce4d0b8544c8de2f7acaa9a6d73171f04460388b2b6d7d6b6c256aea4ebb8780140781596 languageName: node linkType: hard -"jest-jasmine2@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-jasmine2@npm:24.9.0" +"jest-jasmine2@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-jasmine2@npm:26.6.3" dependencies: "@babel/traverse": ^7.1.0 - "@jest/environment": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - chalk: ^2.0.1 + "@jest/environment": ^26.6.2 + "@jest/source-map": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + chalk: ^4.0.0 co: ^4.6.0 - expect: ^24.9.0 + expect: ^26.6.2 is-generator-fn: ^2.0.0 - jest-each: ^24.9.0 - jest-matcher-utils: ^24.9.0 - jest-message-util: ^24.9.0 - jest-runtime: ^24.9.0 - jest-snapshot: ^24.9.0 - jest-util: ^24.9.0 - pretty-format: ^24.9.0 - throat: ^4.0.0 - checksum: 0ce903a12f5c237565e033d6e97bbb22d3131f918d4f715f6908950d820424c780b2f7020b9771001cede4e0a76bd06592fff99924b84cafbc8353feb38667aa + jest-each: ^26.6.2 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-runtime: ^26.6.3 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + pretty-format: ^26.6.2 + throat: ^5.0.0 + checksum: 41df0b993ae0cdeb2660fb3d8e88e2dcc83aec6b5c27d85eb233c2d507b546f8dce45fc54898ffbefa48ccc4633f225d0e023fd0979b8f7f2f1626074a69a9a3 languageName: node linkType: hard -"jest-leak-detector@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-leak-detector@npm:24.9.0" +"jest-leak-detector@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-leak-detector@npm:26.6.2" dependencies: - jest-get-type: ^24.9.0 - pretty-format: ^24.9.0 - checksum: ab54f8ca8f9abf76db9f681b8add50a17767e7b15459710ece030bd034e1fad47c67da73562408779839138dc7423a08f387f5930efdd800eac67d5653badce8 + jest-get-type: ^26.3.0 + pretty-format: ^26.6.2 + checksum: 364dd4d021347e26c66ba9c09da8a30477f14a3a8a208d2d7d64e4c396db81b85d8cb6b6834bcfc47a61b5938e274553957d11a7de2255f058c9d55d7f8fdfe7 languageName: node linkType: hard @@ -11039,239 +12001,267 @@ __metadata: languageName: node linkType: hard -"jest-matcher-utils@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-matcher-utils@npm:24.9.0" +"jest-matcher-utils@npm:^26.6.0, jest-matcher-utils@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-matcher-utils@npm:26.6.2" dependencies: - chalk: ^2.0.1 - jest-diff: ^24.9.0 - jest-get-type: ^24.9.0 - pretty-format: ^24.9.0 - checksum: e9dcd4c7a0bf52dccb4890de7ac2da3e857af067e71633b730fdc865dd271b8a2c3d68a2761d5ca6060ea4a455be42176f58462006468b8eb7c216921251e2ee + chalk: ^4.0.0 + jest-diff: ^26.6.2 + jest-get-type: ^26.3.0 + pretty-format: ^26.6.2 + checksum: 74d2165c1ac7fe98fe27cd2b5407499478e6b2fe99dd54e26d8ee5c9f5f913bdd7bdc07c7221b9b04df0c15e9be0e866ff3455b03e38cc66c480d9996d6d5405 languageName: node linkType: hard -"jest-message-util@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-message-util@npm:24.9.0" +"jest-message-util@npm:^26.6.0, jest-message-util@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-message-util@npm:26.6.2" dependencies: "@babel/code-frame": ^7.0.0 - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - "@types/stack-utils": ^1.0.1 - chalk: ^2.0.1 - micromatch: ^3.1.10 - slash: ^2.0.0 - stack-utils: ^1.0.1 - checksum: c173117b245090967db4853c28c3452ad2987a10caf28161abbfeb8d96be13f0d9e25422df10162bcc5e46860887e35ec4b4963f85392c4a625e4c37ad242f0b + "@jest/types": ^26.6.2 + "@types/stack-utils": ^2.0.0 + chalk: ^4.0.0 + graceful-fs: ^4.2.4 + micromatch: ^4.0.2 + pretty-format: ^26.6.2 + slash: ^3.0.0 + stack-utils: ^2.0.2 + checksum: ffe5a715591c41240b9ed4092faf10f3eaf9ddfdf25d257a0c9f903aaa8d9eed5baa7e38016d2ec4f610fd29225e0f5231a91153e087a043e62824972c83d015 languageName: node linkType: hard -"jest-mock@npm:^24.0.0, jest-mock@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-mock@npm:24.9.0" +"jest-mock@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-mock@npm:26.6.2" dependencies: - "@jest/types": ^24.9.0 - checksum: 823feac37b003543fe81e05d5d8a1ec69cdf9ae5b797582a3e90424ec476120ce42a11e6b1d8231958e01232d4e40e57207cf2c56197d63d309bdeaf63fcf804 + "@jest/types": ^26.6.2 + "@types/node": "*" + checksum: 6c0fe028ff0cdc87b5d63b9ca749af04cae6c5577aaab234f602e546cae3f4b932adac9d77e6de2abb24955ee00978e1e5d5a861725654e2f9a42317d91fbc1f languageName: node linkType: hard -"jest-pnp-resolver@npm:^1.2.1": - version: 1.2.2 - resolution: "jest-pnp-resolver@npm:1.2.2" +"jest-pnp-resolver@npm:^1.2.2": + version: 1.2.3 + resolution: "jest-pnp-resolver@npm:1.2.3" peerDependencies: jest-resolve: "*" peerDependenciesMeta: jest-resolve: optional: true - checksum: bd85dcc0e76e0eb0c3d56382ec140f08d25ff4068cda9d0e360bb78fb176cb726d0beab82dc0e8694cafd09f55fee7622b8bcb240afa5fad301f4ed3eebb4f47 + checksum: db1a8ab2cb97ca19c01b1cfa9a9c8c69a143fde833c14df1fab0766f411b1148ff0df878adea09007ac6a2085ec116ba9a996a6ad104b1e58c20adbf88eed9b2 languageName: node linkType: hard -"jest-regex-util@npm:^24.3.0, jest-regex-util@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-regex-util@npm:24.9.0" - checksum: 94299972501ae5dfc3932673b263fd15dba5e28698571687a28cc59b5a173edcbf52b992f4d5a6eded9da5b7e1468d263ef96a1564267832799b41c2986fc423 +"jest-regex-util@npm:^26.0.0": + version: 26.0.0 + resolution: "jest-regex-util@npm:26.0.0" + checksum: 930a00665e8dfbedc29140678b4a54f021b41b895cf35050f76f557c1da3ac48ff42dd7b18ba2ccba6f4e518c6445d6753730d03ec7049901b93992db1ef0483 languageName: node linkType: hard -"jest-resolve-dependencies@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-resolve-dependencies@npm:24.9.0" +"jest-resolve-dependencies@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-resolve-dependencies@npm:26.6.3" dependencies: - "@jest/types": ^24.9.0 - jest-regex-util: ^24.3.0 - jest-snapshot: ^24.9.0 - checksum: 126627777e7382b7ecc5b342f5f7b0e247a99e35895ee59282e7066c611d58ff2bd6a7332628e44e221a52361b8ecd1d9de41ba20d240f9b621ee80b6aebf820 + "@jest/types": ^26.6.2 + jest-regex-util: ^26.0.0 + jest-snapshot: ^26.6.2 + checksum: 533ea1e271426006ff02c03c9802b108fcd68f2144615b6110ae59f3a0a2cc4a7abb3f44c3c65299c76b3a725d5d8220aaed9c58b79c8c8c508c18699a96e3f7 languageName: node linkType: hard -"jest-resolve@npm:24.9.0, jest-resolve@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-resolve@npm:24.9.0" +"jest-resolve@npm:26.6.0": + version: 26.6.0 + resolution: "jest-resolve@npm:26.6.0" dependencies: - "@jest/types": ^24.9.0 - browser-resolve: ^1.11.3 - chalk: ^2.0.1 - jest-pnp-resolver: ^1.2.1 - realpath-native: ^1.1.0 - checksum: 60a84cbd75d5cdab1ad29c8ed62e43fbc374c906e5a0f166fae5170f91c863ee9372aaab7dbdb3a06a38b0362131fa7c907c114be76a8bc1aeac47013ec308e4 + "@jest/types": ^26.6.0 + chalk: ^4.0.0 + graceful-fs: ^4.2.4 + jest-pnp-resolver: ^1.2.2 + jest-util: ^26.6.0 + read-pkg-up: ^7.0.1 + resolve: ^1.17.0 + slash: ^3.0.0 + checksum: c5d0277d4aa22f9f38693ba3e5d6176edf2e367af2f0c38e16c88e9b80b2292ee4d9df9b3675607f5d0c0b2652b4e3f69d8155f9fedd83ddd0ef937cfb6230c0 languageName: node linkType: hard -"jest-runner@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-runner@npm:24.9.0" +"jest-resolve@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-resolve@npm:26.6.2" dependencies: - "@jest/console": ^24.7.1 - "@jest/environment": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - chalk: ^2.4.2 + "@jest/types": ^26.6.2 + chalk: ^4.0.0 + graceful-fs: ^4.2.4 + jest-pnp-resolver: ^1.2.2 + jest-util: ^26.6.2 + read-pkg-up: ^7.0.1 + resolve: ^1.18.1 + slash: ^3.0.0 + checksum: d6264d3f39b098753802a237c8c54f3109f5f3b3b7fa6f8d7aec7dca01b357ddf518ce1c33a68454357c15f48fb3c6026a92b9c4f5d72f07e24e80f04bcc8d58 + languageName: node + linkType: hard + +"jest-runner@npm:^26.6.0, jest-runner@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-runner@npm:26.6.3" + dependencies: + "@jest/console": ^26.6.2 + "@jest/environment": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + chalk: ^4.0.0 + emittery: ^0.7.1 exit: ^0.1.2 - graceful-fs: ^4.1.15 - jest-config: ^24.9.0 - jest-docblock: ^24.3.0 - jest-haste-map: ^24.9.0 - jest-jasmine2: ^24.9.0 - jest-leak-detector: ^24.9.0 - jest-message-util: ^24.9.0 - jest-resolve: ^24.9.0 - jest-runtime: ^24.9.0 - jest-util: ^24.9.0 - jest-worker: ^24.6.0 + graceful-fs: ^4.2.4 + jest-config: ^26.6.3 + jest-docblock: ^26.0.0 + jest-haste-map: ^26.6.2 + jest-leak-detector: ^26.6.2 + jest-message-util: ^26.6.2 + jest-resolve: ^26.6.2 + jest-runtime: ^26.6.3 + jest-util: ^26.6.2 + jest-worker: ^26.6.2 source-map-support: ^0.5.6 - throat: ^4.0.0 - checksum: cb5c9fe598ca4ce8d13c2cf8b1649573e1bc73a50eb9438719b33970fed35ee75f731d64090d3392990f077ac1974119d094e311f503884eab42fa10081bd8a3 + throat: ^5.0.0 + checksum: ccd69918baa49a5efa45985cf60cfa1fbb1686b32d7a86296b7b55f89684e36d1f08e62598c4b7be7e81f2cf2e245d1a65146ea7bdcaedfa6ed176d3e645d7e2 languageName: node linkType: hard -"jest-runtime@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-runtime@npm:24.9.0" - dependencies: - "@jest/console": ^24.7.1 - "@jest/environment": ^24.9.0 - "@jest/source-map": ^24.3.0 - "@jest/transform": ^24.9.0 - "@jest/types": ^24.9.0 - "@types/yargs": ^13.0.0 - chalk: ^2.0.1 +"jest-runtime@npm:^26.6.0, jest-runtime@npm:^26.6.3": + version: 26.6.3 + resolution: "jest-runtime@npm:26.6.3" + dependencies: + "@jest/console": ^26.6.2 + "@jest/environment": ^26.6.2 + "@jest/fake-timers": ^26.6.2 + "@jest/globals": ^26.6.2 + "@jest/source-map": ^26.6.2 + "@jest/test-result": ^26.6.2 + "@jest/transform": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/yargs": ^15.0.0 + chalk: ^4.0.0 + cjs-module-lexer: ^0.6.0 + collect-v8-coverage: ^1.0.0 exit: ^0.1.2 glob: ^7.1.3 - graceful-fs: ^4.1.15 - jest-config: ^24.9.0 - jest-haste-map: ^24.9.0 - jest-message-util: ^24.9.0 - jest-mock: ^24.9.0 - jest-regex-util: ^24.3.0 - jest-resolve: ^24.9.0 - jest-snapshot: ^24.9.0 - jest-util: ^24.9.0 - jest-validate: ^24.9.0 - realpath-native: ^1.1.0 - slash: ^2.0.0 - strip-bom: ^3.0.0 - yargs: ^13.3.0 + graceful-fs: ^4.2.4 + jest-config: ^26.6.3 + jest-haste-map: ^26.6.2 + jest-message-util: ^26.6.2 + jest-mock: ^26.6.2 + jest-regex-util: ^26.0.0 + jest-resolve: ^26.6.2 + jest-snapshot: ^26.6.2 + jest-util: ^26.6.2 + jest-validate: ^26.6.2 + slash: ^3.0.0 + strip-bom: ^4.0.0 + yargs: ^15.4.1 bin: - jest-runtime: ./bin/jest-runtime.js - checksum: 924afebac3f1aaf8d9d6dec1b949d1c082b59a26c1b8917a7c47bf9bd27ad05544d534748119616b7f4e99ff50f546f25ca8b3f9bf32a34504355b8059bd0d45 + jest-runtime: bin/jest-runtime.js + checksum: 867922b49f9ab4cf2f5f1356ac3d9962c4477c7a2ff696cc841ea4c600ea389e7d6dfcbf945fec6849e606f81980addf31e4f34d63eaa3d3415f4901de2f605a languageName: node linkType: hard -"jest-serializer@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-serializer@npm:24.9.0" - checksum: 56d70bd50ebd71de7a38e1f94ef2fdf1293c3810ef6d372b69238263625d3df1e6749417872bc6be0515e39832f4c40df03c74d20d8f0f43efd14ea21e22178d +"jest-serializer@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-serializer@npm:26.6.2" + dependencies: + "@types/node": "*" + graceful-fs: ^4.2.4 + checksum: dbecfb0d01462fe486a0932cf1680cf6abb204c059db2a8f72c6c2a7c9842a82f6d256874112774cea700764ed8f38fc9e3db982456c138d87353e3390e746fe languageName: node linkType: hard -"jest-snapshot@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-snapshot@npm:24.9.0" +"jest-snapshot@npm:^26.6.0, jest-snapshot@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-snapshot@npm:26.6.2" dependencies: "@babel/types": ^7.0.0 - "@jest/types": ^24.9.0 - chalk: ^2.0.1 - expect: ^24.9.0 - jest-diff: ^24.9.0 - jest-get-type: ^24.9.0 - jest-matcher-utils: ^24.9.0 - jest-message-util: ^24.9.0 - jest-resolve: ^24.9.0 - mkdirp: ^0.5.1 + "@jest/types": ^26.6.2 + "@types/babel__traverse": ^7.0.4 + "@types/prettier": ^2.0.0 + chalk: ^4.0.0 + expect: ^26.6.2 + graceful-fs: ^4.2.4 + jest-diff: ^26.6.2 + jest-get-type: ^26.3.0 + jest-haste-map: ^26.6.2 + jest-matcher-utils: ^26.6.2 + jest-message-util: ^26.6.2 + jest-resolve: ^26.6.2 natural-compare: ^1.4.0 - pretty-format: ^24.9.0 - semver: ^6.2.0 - checksum: 474dc05ededdb8b39fb79801498fcd16c1a13a01b4701a27172be0ee3ebc5640e2bfb2780a9afa49bd825b19fc2be1e2ec5fc3d501afa76a5f7bc40f0120aaf3 + pretty-format: ^26.6.2 + semver: ^7.3.2 + checksum: 53f1de055b1d3840bc6e851fd674d5991b844d4695dadbd07354c93bf191048d8767b8606999847e97c4214a485b9afb45c1d2411772befa1870414ac973b3e2 languageName: node linkType: hard -"jest-util@npm:^24.0.0, jest-util@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-util@npm:24.9.0" +"jest-util@npm:^26.6.0, jest-util@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-util@npm:26.6.2" dependencies: - "@jest/console": ^24.9.0 - "@jest/fake-timers": ^24.9.0 - "@jest/source-map": ^24.9.0 - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - callsites: ^3.0.0 - chalk: ^2.0.1 - graceful-fs: ^4.1.15 + "@jest/types": ^26.6.2 + "@types/node": "*" + chalk: ^4.0.0 + graceful-fs: ^4.2.4 is-ci: ^2.0.0 - mkdirp: ^0.5.1 - slash: ^2.0.0 - source-map: ^0.6.0 - checksum: ee84238bfb8c4aa60830b546e0e5dbdff53bbe55a1462f023182130ee7f1f3aac2dce0ab8395ab72b93e5a889fa12a55cebeeab04352a623d00d29c262dfbeb0 + micromatch: ^4.0.2 + checksum: 3c6a5fba05c4c6892cd3a9f66196ea8867087b77a5aa1a3f6cd349c785c3f1ca24abfd454664983aed1a165cab7846688e44fe8630652d666ba326b08625bc3d languageName: node linkType: hard -"jest-validate@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-validate@npm:24.9.0" +"jest-validate@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-validate@npm:26.6.2" dependencies: - "@jest/types": ^24.9.0 - camelcase: ^5.3.1 - chalk: ^2.0.1 - jest-get-type: ^24.9.0 + "@jest/types": ^26.6.2 + camelcase: ^6.0.0 + chalk: ^4.0.0 + jest-get-type: ^26.3.0 leven: ^3.1.0 - pretty-format: ^24.9.0 - checksum: 8e9abc2b605a10e9872bd7cc9cd676641b781b16f22028b7ed59cb3243e942065229e804bf5aa3c9e2d62a1444dd492193155bb7e02d9e6e330faa0afbb6dd9f + pretty-format: ^26.6.2 + checksum: bac11d6586d9b8885328a4a66eec45b692e45ac23034a5c09eb0ee32de324f2d3d52b073e0c34e9c222b3642b083d1152a736cf24c52109e4957537d731ca62b languageName: node linkType: hard -"jest-watch-typeahead@npm:0.4.2": - version: 0.4.2 - resolution: "jest-watch-typeahead@npm:0.4.2" +"jest-watch-typeahead@npm:0.6.1": + version: 0.6.1 + resolution: "jest-watch-typeahead@npm:0.6.1" dependencies: - ansi-escapes: ^4.2.1 - chalk: ^2.4.1 - jest-regex-util: ^24.9.0 - jest-watcher: ^24.3.0 + ansi-escapes: ^4.3.1 + chalk: ^4.0.0 + jest-regex-util: ^26.0.0 + jest-watcher: ^26.3.0 slash: ^3.0.0 - string-length: ^3.1.0 - strip-ansi: ^5.0.0 - checksum: d65675b8a374307199852693feecf76c16e455910478eb1495d51ec5be66d08b6601e17274249ecce42454452bb202c7fea95262a3cfb5b16c8d50833e46f0db + string-length: ^4.0.1 + strip-ansi: ^6.0.0 + peerDependencies: + jest: ^26.0.0 + checksum: a65dfd080e68b79ce7c861ec07791a0768820049a1d6a471d01f3fc41ee88723db29b434e19c917421e7f34ec567bcade368f3671e234c557288e206f7fd4257 languageName: node linkType: hard -"jest-watcher@npm:^24.3.0, jest-watcher@npm:^24.9.0": - version: 24.9.0 - resolution: "jest-watcher@npm:24.9.0" +"jest-watcher@npm:^26.3.0, jest-watcher@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-watcher@npm:26.6.2" dependencies: - "@jest/test-result": ^24.9.0 - "@jest/types": ^24.9.0 - "@types/yargs": ^13.0.0 - ansi-escapes: ^3.0.0 - chalk: ^2.0.1 - jest-util: ^24.9.0 - string-length: ^2.0.0 - checksum: c0ceec6e854ee73a196064e51471fe01ff743ca78df8f4ef1c78194a0fd4f43ece26d2c55d011e258ac7ae0f37eaecbe3cc100defb604124d90cd9473538a97b + "@jest/test-result": ^26.6.2 + "@jest/types": ^26.6.2 + "@types/node": "*" + ansi-escapes: ^4.2.1 + chalk: ^4.0.0 + jest-util: ^26.6.2 + string-length: ^4.0.1 + checksum: 401137f1a73bf23cdf390019ebffb3f6f89c53ca49d48252d1dd6daf17a68787fef75cc55a623de28b63d87d0e8f13d8972d7dd06740f2f64f7b2a0409d119d2 languageName: node linkType: hard -"jest-worker@npm:^24.6.0, jest-worker@npm:^24.9.0": +"jest-worker@npm:^24.9.0": version: 24.9.0 resolution: "jest-worker@npm:24.9.0" dependencies: @@ -11281,29 +12271,42 @@ __metadata: languageName: node linkType: hard -"jest-worker@npm:^25.4.0": - version: 25.5.0 - resolution: "jest-worker@npm:25.5.0" +"jest-worker@npm:^26.5.0, jest-worker@npm:^26.6.2": + version: 26.6.2 + resolution: "jest-worker@npm:26.6.2" dependencies: + "@types/node": "*" merge-stream: ^2.0.0 supports-color: ^7.0.0 - checksum: 773ad5c680f7c47c023e90a63faffe041dc297c19df90d31768598d700517ef31ad5e3289e68bdf85ab7eca91efde8134f8646472747f47ae3f60c96a37d1c4b + checksum: f9afa3b88e3f12027901e4964ba3ff048285b5783b5225cab28fac25b4058cea8ad54001e9a1577ee2bed125fac3ccf5c80dc507b120300cc1bbcb368796533e languageName: node linkType: hard -"jest@npm:24.9.0": - version: 24.9.0 - resolution: "jest@npm:24.9.0" +"jest-worker@npm:^27.5.1": + version: 27.5.1 + resolution: "jest-worker@npm:27.5.1" dependencies: - import-local: ^2.0.0 - jest-cli: ^24.9.0 + "@types/node": "*" + merge-stream: ^2.0.0 + supports-color: ^8.0.0 + checksum: 98cd68b696781caed61c983a3ee30bf880b5bd021c01d98f47b143d4362b85d0737f8523761e2713d45e18b4f9a2b98af1eaee77afade4111bb65c77d6f7c980 + languageName: node + linkType: hard + +"jest@npm:26.6.0": + version: 26.6.0 + resolution: "jest@npm:26.6.0" + dependencies: + "@jest/core": ^26.6.0 + import-local: ^3.0.2 + jest-cli: ^26.6.0 bin: - jest: ./bin/jest.js - checksum: 7bc61d47f94b18d52f354d785a9743883045222d0f1309a1131f0843479bdf8d98de1d62b9f519a562e99f883c51bd8af6a52f9e5a19596dae97d835abbc2cff + jest: bin/jest.js + checksum: e0d3efff0dc2a31c453a3f7d87586e5d6c0f008c9b827bb9204edde09288f922ddfb3a8917480bf68f4ac0298be28637daef98ebaaac65ea23d3cb754a6620c4 languageName: node linkType: hard -"js-base64@npm:^2.1.8, js-base64@npm:^2.4.9": +"js-base64@npm:^2.4.9": version: 2.6.4 resolution: "js-base64@npm:2.6.4" checksum: 5f4084078d6c46f8529741d110df84b14fac3276b903760c21fa8cc8521370d607325dfe1c1a9fbbeaae1ff8e602665aaeef1362427d8fef704f9e3659472ce8 @@ -11317,13 +12320,6 @@ __metadata: languageName: node linkType: hard -"js-tokens@npm:^3.0.2": - version: 3.0.2 - resolution: "js-tokens@npm:3.0.2" - checksum: ff24cf90e6e4ac446eba56e604781c1aaf3bdaf9b13a00596a0ebd972fa3b25dc83c0f0f67289c33252abb4111e0d14e952a5d9ffb61f5c22532d555ebd8d8a9 - languageName: node - linkType: hard - "js-yaml@npm:3.13.1": version: 3.13.1 resolution: "js-yaml@npm:3.13.1" @@ -11355,71 +12351,43 @@ __metadata: languageName: node linkType: hard -"jsdom@npm:^11.5.1": - version: 11.12.0 - resolution: "jsdom@npm:11.12.0" - dependencies: - abab: ^2.0.0 - acorn: ^5.5.3 - acorn-globals: ^4.1.0 - array-equal: ^1.0.0 - cssom: ">= 0.3.2 < 0.4.0" - cssstyle: ^1.0.0 - data-urls: ^1.0.0 - domexception: ^1.0.1 - escodegen: ^1.9.1 - html-encoding-sniffer: ^1.0.2 - left-pad: ^1.3.0 - nwsapi: ^2.0.7 - parse5: 4.0.0 - pn: ^1.1.0 - request: ^2.87.0 - request-promise-native: ^1.0.5 - sax: ^1.2.4 - symbol-tree: ^3.2.2 - tough-cookie: ^2.3.4 - w3c-hr-time: ^1.0.1 - webidl-conversions: ^4.0.2 - whatwg-encoding: ^1.0.3 - whatwg-mimetype: ^2.1.0 - whatwg-url: ^6.4.1 - ws: ^5.2.0 - xml-name-validator: ^3.0.0 - checksum: 1dab757e92ce857df648ebec3dbe487954f886652faf9d97953c3b502958b1e4487e147baef5494718294e8625ae238e68354db710456fa73c394fb93dbfc68b - languageName: node - linkType: hard - -"jsdom@npm:^14.1.0": - version: 14.1.0 - resolution: "jsdom@npm:14.1.0" - dependencies: - abab: ^2.0.0 - acorn: ^6.0.4 - acorn-globals: ^4.3.0 - array-equal: ^1.0.0 - cssom: ^0.3.4 - cssstyle: ^1.1.1 - data-urls: ^1.1.0 - domexception: ^1.0.1 - escodegen: ^1.11.0 - html-encoding-sniffer: ^1.0.2 - nwsapi: ^2.1.3 - parse5: 5.1.0 - pn: ^1.1.0 - request: ^2.88.0 - request-promise-native: ^1.0.5 - saxes: ^3.1.9 - symbol-tree: ^3.2.2 - tough-cookie: ^2.5.0 - w3c-hr-time: ^1.0.1 - w3c-xmlserializer: ^1.1.2 - webidl-conversions: ^4.0.2 +"jsdom@npm:^16.4.0": + version: 16.7.0 + resolution: "jsdom@npm:16.7.0" + dependencies: + abab: ^2.0.5 + acorn: ^8.2.4 + acorn-globals: ^6.0.0 + cssom: ^0.4.4 + cssstyle: ^2.3.0 + data-urls: ^2.0.0 + decimal.js: ^10.2.1 + domexception: ^2.0.1 + escodegen: ^2.0.0 + form-data: ^3.0.0 + html-encoding-sniffer: ^2.0.1 + http-proxy-agent: ^4.0.1 + https-proxy-agent: ^5.0.0 + is-potential-custom-element-name: ^1.0.1 + nwsapi: ^2.2.0 + parse5: 6.0.1 + saxes: ^5.0.1 + symbol-tree: ^3.2.4 + tough-cookie: ^4.0.0 + w3c-hr-time: ^1.0.2 + w3c-xmlserializer: ^2.0.0 + webidl-conversions: ^6.1.0 whatwg-encoding: ^1.0.5 whatwg-mimetype: ^2.3.0 - whatwg-url: ^7.0.0 - ws: ^6.1.2 + whatwg-url: ^8.5.0 + ws: ^7.4.6 xml-name-validator: ^3.0.0 - checksum: c8ece2c4324be30536411a5ef9e52ebccefeb1605bd1ba31d14e40ab576a40a0e7d009bd89edd0e422654e4518383bb1f4ab6f574ccecaf98e5839c200fd7772 + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + checksum: 454b83371857000763ed31130a049acd1b113e3b927e6dcd75c67ddc30cdd242d7ebcac5c2294b7a1a6428155cb1398709c573b3c6d809218692ea68edd93370 languageName: node linkType: hard @@ -11441,6 +12409,13 @@ __metadata: languageName: node linkType: hard +"json-buffer@npm:3.0.1": + version: 3.0.1 + resolution: "json-buffer@npm:3.0.1" + checksum: 9026b03edc2847eefa2e37646c579300a1f3a4586cfb62bf857832b60c852042d0d6ae55d1afb8926163fa54c2b01d83ae24705f34990348bdac6273a29d4581 + languageName: node + linkType: hard + "json-parse-better-errors@npm:^1.0.1, json-parse-better-errors@npm:^1.0.2": version: 1.0.2 resolution: "json-parse-better-errors@npm:1.0.2" @@ -11462,6 +12437,13 @@ __metadata: languageName: node linkType: hard +"json-schema-traverse@npm:^1.0.0": + version: 1.0.0 + resolution: "json-schema-traverse@npm:1.0.0" + checksum: 02f2f466cdb0362558b2f1fd5e15cce82ef55d60cd7f8fa828cf35ba74330f8d767fcae5c5c2adb7851fa811766c694b9405810879bc4e1ddd78a7c0e03658ad + languageName: node + linkType: hard + "json-schema@npm:0.4.0": version: 0.4.0 resolution: "json-schema@npm:0.4.0" @@ -11476,15 +12458,6 @@ __metadata: languageName: node linkType: hard -"json-stable-stringify@npm:^1.0.1": - version: 1.0.1 - resolution: "json-stable-stringify@npm:1.0.1" - dependencies: - jsonify: ~0.0.0 - checksum: 65d6cbf0fca72a4136999f65f4401cf39a129f7aeff0fdd987ac3d3423a2113659294045fb8377e6e20d865cac32b1b8d70f3d87346c9786adcee60661d96ca5 - languageName: node - linkType: hard - "json-stringify-safe@npm:~5.0.1": version: 5.0.1 resolution: "json-stringify-safe@npm:5.0.1" @@ -11499,7 +12472,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^1.0.1": +"json5@npm:^1.0.1, json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" dependencies: @@ -11544,10 +12517,14 @@ __metadata: languageName: node linkType: hard -"jsonify@npm:~0.0.0": - version: 0.0.0 - resolution: "jsonify@npm:0.0.0" - checksum: d8d4ed476c116e6987a460dcb82f22284686caae9f498ac87b0502c1765ac1522f4f450a4cad4cc368d202fd3b27a3860735140a82867fc6d558f5f199c38bce +"jsonpath@npm:^1.1.1": + version: 1.1.1 + resolution: "jsonpath@npm:1.1.1" + dependencies: + esprima: 1.2.2 + static-eval: 2.0.2 + underscore: 1.12.1 + checksum: 5480d8e9e424fe2ed4ade6860b6e2cefddb21adb3a99abe0254cd9428e8ef9b0c9fb5729d6a5a514e90df50d645ccea9f3be48d627570e6222dd5dadc28eba7b languageName: node linkType: hard @@ -11653,13 +12630,15 @@ __metadata: languageName: node linkType: hard -"jsx-ast-utils@npm:^2.2.1, jsx-ast-utils@npm:^2.2.3": - version: 2.4.1 - resolution: "jsx-ast-utils@npm:2.4.1" +"jsx-ast-utils@npm:^2.4.1 || ^3.0.0, jsx-ast-utils@npm:^3.3.5": + version: 3.3.5 + resolution: "jsx-ast-utils@npm:3.3.5" dependencies: - array-includes: ^3.1.1 - object.assign: ^4.1.0 - checksum: 833477231266631e0def7ab5fa5da386790130ce5f9ab5db22fb3a8e67ee0adba9082ff27687e5c64c893af00beeb2285a7309cbc40c5edbcafdaf4e9de069a1 + array-includes: ^3.1.6 + array.prototype.flat: ^1.3.1 + object.assign: ^4.1.4 + object.values: ^1.1.6 + checksum: f4b05fa4d7b5234230c905cfa88d36dc8a58a6666975a3891429b1a8cdc8a140bca76c297225cb7a499fad25a2c052ac93934449a2c31a44fc9edd06c773780a languageName: node linkType: hard @@ -11682,6 +12661,15 @@ __metadata: languageName: node linkType: hard +"keyv@npm:^4.5.3": + version: 4.5.4 + resolution: "keyv@npm:4.5.4" + dependencies: + json-buffer: 3.0.1 + checksum: 74a24395b1c34bd44ad5cb2b49140d087553e170625240b86755a6604cd65aa16efdbdeae5cdb17ba1284a0fbb25ad06263755dbc71b8d8b06f74232ce3cdd72 + languageName: node + linkType: hard + "killable@npm:^1.0.1": version: 1.0.1 resolution: "killable@npm:1.0.1" @@ -11689,15 +12677,6 @@ __metadata: languageName: node linkType: hard -"kind-of@npm:^2.0.1": - version: 2.0.1 - resolution: "kind-of@npm:2.0.1" - dependencies: - is-buffer: ^1.0.2 - checksum: 043df2943e113bca612d26224947395e9673bb3808d94aed30e47fbf0bafd618e2a29ff0ca2d5498f64332c320fff07f0aa9d6edfc20906a93c1b8792f11759c - languageName: node - linkType: hard - "kind-of@npm:^3.0.2, kind-of@npm:^3.0.3, kind-of@npm:^3.2.0": version: 3.2.2 resolution: "kind-of@npm:3.2.2" @@ -11737,6 +12716,22 @@ __metadata: languageName: node linkType: hard +"language-subtag-registry@npm:^0.3.20": + version: 0.3.22 + resolution: "language-subtag-registry@npm:0.3.22" + checksum: 8ab70a7e0e055fe977ac16ea4c261faec7205ac43db5e806f72e5b59606939a3b972c4bd1e10e323b35d6ffa97c3e1c4c99f6553069dad2dfdd22020fa3eb56a + languageName: node + linkType: hard + +"language-tags@npm:^1.0.9": + version: 1.0.9 + resolution: "language-tags@npm:1.0.9" + dependencies: + language-subtag-registry: ^0.3.20 + checksum: 57c530796dc7179914dee71bc94f3747fd694612480241d0453a063777265dfe3a951037f7acb48f456bf167d6eb419d4c00263745326b3ba1cdcf4657070e78 + languageName: node + linkType: hard + "last-call-webpack-plugin@npm:^3.0.0": version: 3.0.0 resolution: "last-call-webpack-plugin@npm:3.0.0" @@ -11754,36 +12749,6 @@ __metadata: languageName: node linkType: hard -"lazy-cache@npm:^0.2.3": - version: 0.2.7 - resolution: "lazy-cache@npm:0.2.7" - checksum: b4538aff20db586c354f31de3ed59ea2c8d5dc4f01141bf49f07601e7ca0d7ed43a3f49362ade49b1e18ab1f3d121df0f2c9ea9b599b44dd54fb0c0db253c8b9 - languageName: node - linkType: hard - -"lazy-cache@npm:^1.0.3": - version: 1.0.4 - resolution: "lazy-cache@npm:1.0.4" - checksum: e6650c22e5de1cc3f4a0c25d2b35fe9cd400473c1b3562be9fceadf8f368d708b54d24f5aa51b321b090da65b36426823a8f706b8dbdd68270db0daba812c5d3 - languageName: node - linkType: hard - -"lcid@npm:^1.0.0": - version: 1.0.0 - resolution: "lcid@npm:1.0.0" - dependencies: - invert-kv: ^1.0.0 - checksum: e8c7a4db07663068c5c44b650938a2bc41aa992037eebb69376214320f202c1250e70b50c32f939e28345fd30c2d35b8e8cd9a19d5932c398246a864ce54843d - languageName: node - linkType: hard - -"left-pad@npm:^1.3.0": - version: 1.3.0 - resolution: "left-pad@npm:1.3.0" - checksum: 13fa96e17b70a54836490de22d4bab706e2ed508338bbabecfac72ecce445a74139c5b009a8112252cab8fc4ab7ac4ebd870e5b35bd236b443b12be96f8745ac - languageName: node - linkType: hard - "leven@npm:^3.1.0": version: 3.1.0 resolution: "leven@npm:3.1.0" @@ -11791,16 +12756,17 @@ __metadata: languageName: node linkType: hard -"levenary@npm:^1.1.1": - version: 1.1.1 - resolution: "levenary@npm:1.1.1" +"levn@npm:^0.4.1": + version: 0.4.1 + resolution: "levn@npm:0.4.1" dependencies: - leven: ^3.1.0 - checksum: d292b002e278c2b7e33fe0856920363a6abe61373c04c702bce3dfc324069a52b52ceb8c87d6b6032a074020425e56f2fd0c0a99f577511fabd1674a12df3282 + prelude-ls: ^1.2.1 + type-check: ~0.4.0 + checksum: 12c5021c859bd0f5248561bf139121f0358285ec545ebf48bb3d346820d5c61a4309535c7f387ed7d84361cf821e124ce346c6b7cef8ee09a67c1473b46d0fc4 languageName: node linkType: hard -"levn@npm:^0.3.0, levn@npm:~0.3.0": +"levn@npm:~0.3.0": version: 0.3.0 resolution: "levn@npm:0.3.0" dependencies: @@ -11847,53 +12813,6 @@ __metadata: languageName: node linkType: hard -"load-json-file@npm:^1.0.0": - version: 1.1.0 - resolution: "load-json-file@npm:1.1.0" - dependencies: - graceful-fs: ^4.1.2 - parse-json: ^2.2.0 - pify: ^2.0.0 - pinkie-promise: ^2.0.0 - strip-bom: ^2.0.0 - checksum: 0e4e4f380d897e13aa236246a917527ea5a14e4fc34d49e01ce4e7e2a1e08e2740ee463a03fb021c04f594f29a178f4adb994087549d7c1c5315fcd29bf9934b - languageName: node - linkType: hard - -"load-json-file@npm:^2.0.0": - version: 2.0.0 - resolution: "load-json-file@npm:2.0.0" - dependencies: - graceful-fs: ^4.1.2 - parse-json: ^2.2.0 - pify: ^2.0.0 - strip-bom: ^3.0.0 - checksum: 7f212bbf08a8c9aab087ead07aa220d1f43d83ec1c4e475a00a8d9bf3014eb29ebe901db8554627dcfb70184c274d05b7379f1e9678fe8297ae74dc495212049 - languageName: node - linkType: hard - -"load-json-file@npm:^4.0.0": - version: 4.0.0 - resolution: "load-json-file@npm:4.0.0" - dependencies: - graceful-fs: ^4.1.2 - parse-json: ^4.0.0 - pify: ^3.0.0 - strip-bom: ^3.0.0 - checksum: 8f5d6d93ba64a9620445ee9bde4d98b1eac32cf6c8c2d20d44abfa41a6945e7969456ab5f1ca2fb06ee32e206c9769a20eec7002fe290de462e8c884b6b8b356 - languageName: node - linkType: hard - -"loader-fs-cache@npm:^1.0.2": - version: 1.0.3 - resolution: "loader-fs-cache@npm:1.0.3" - dependencies: - find-cache-dir: ^0.1.1 - mkdirp: ^0.5.1 - checksum: 39781412e10bb0d6b5ca1afa9a4bd65e1827c5c51ef9ff746ae3fe8ce0e2cfa3fb96492d6619d8ab305407d20be82a9b244c439df0207f6ced4b98f2861bd372 - languageName: node - linkType: hard - "loader-runner@npm:^2.4.0": version: 2.4.0 resolution: "loader-runner@npm:2.4.0" @@ -11901,14 +12820,14 @@ __metadata: languageName: node linkType: hard -"loader-utils@npm:1.2.3": - version: 1.2.3 - resolution: "loader-utils@npm:1.2.3" +"loader-utils@npm:2.0.0": + version: 2.0.0 + resolution: "loader-utils@npm:2.0.0" dependencies: big.js: ^5.2.2 - emojis-list: ^2.0.0 - json5: ^1.0.1 - checksum: 385407fc2683b6d664276fd41df962296de4a15030bb24389de77b175570c3b56bd896869376ba14cf8b33a9e257e17a91d395739ba7e23b5b68a8749a41df7e + emojis-list: ^3.0.0 + json5: ^2.1.2 + checksum: 6856423131b50b6f5f259da36f498cfd7fc3c3f8bb17777cf87fdd9159e797d4ba4288d9a96415fd8da62c2906960e88f74711dee72d03a9003bddcd0d364a51 languageName: node linkType: hard @@ -11934,16 +12853,6 @@ __metadata: languageName: node linkType: hard -"locate-path@npm:^2.0.0": - version: 2.0.0 - resolution: "locate-path@npm:2.0.0" - dependencies: - p-locate: ^2.0.0 - path-exists: ^3.0.0 - checksum: 02d581edbbbb0fa292e28d96b7de36b5b62c2fa8b5a7e82638ebb33afa74284acf022d3b1e9ae10e3ffb7658fbc49163fcd5e76e7d1baaa7801c3e05a81da755 - languageName: node - linkType: hard - "locate-path@npm:^3.0.0": version: 3.0.0 resolution: "locate-path@npm:3.0.0" @@ -12019,6 +12928,13 @@ __metadata: languageName: node linkType: hard +"lodash.merge@npm:^4.6.2": + version: 4.6.2 + resolution: "lodash.merge@npm:4.6.2" + checksum: ad580b4bdbb7ca1f7abf7e1bce63a9a0b98e370cf40194b03380a46b4ed799c9573029599caebc1b14e3f24b111aef72b96674a56cfa105e0f5ac70546cdc005 + languageName: node + linkType: hard + "lodash.mergewith@npm:4.6.2": version: 4.6.2 resolution: "lodash.mergewith@npm:4.6.2" @@ -12033,14 +12949,7 @@ __metadata: languageName: node linkType: hard -"lodash.sortby@npm:^4.7.0": - version: 4.7.0 - resolution: "lodash.sortby@npm:4.7.0" - checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c - languageName: node - linkType: hard - -"lodash.template@npm:4.5.0, lodash.template@npm:^4.4.0": +"lodash.template@npm:4.5.0, lodash.template@npm:^4.5.0": version: 4.5.0 resolution: "lodash.template@npm:4.5.0" dependencies: @@ -12059,6 +12968,13 @@ __metadata: languageName: node linkType: hard +"lodash.truncate@npm:^4.4.2": + version: 4.4.2 + resolution: "lodash.truncate@npm:4.4.2" + checksum: b463d8a382cfb5f0e71c504dcb6f807a7bd379ff1ea216669aa42c52fc28c54e404bfbd96791aa09e6df0de2c1d7b8f1b7f4b1a61f324d38fe98bc535aeee4f5 + languageName: node + linkType: hard + "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -12066,7 +12982,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:>=3.5 <5, lodash@npm:^4.0.0, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.13, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.2.0, lodash@npm:^4.2.1, lodash@npm:~4.17.10": +"lodash@npm:>=3.5 <5, lodash@npm:^4.17.10, lodash@npm:^4.17.11, lodash@npm:^4.17.14, lodash@npm:^4.17.15, lodash@npm:^4.17.19, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.5, lodash@npm:^4.2.0, lodash@npm:^4.2.1, lodash@npm:^4.7.0, lodash@npm:~4.17.10": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -12129,16 +13045,6 @@ __metadata: languageName: node linkType: hard -"loud-rejection@npm:^1.0.0": - version: 1.6.0 - resolution: "loud-rejection@npm:1.6.0" - dependencies: - currently-unhandled: ^0.4.1 - signal-exit: ^3.0.0 - checksum: 750e12defde34e8cbf263c2bff16f028a89b56e022ad6b368aa7c39495b5ac33f2349a8d00665a9b6d25c030b376396524d8a31eb0dde98aaa97956d7324f927 - languageName: node - linkType: hard - "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -12180,7 +13086,16 @@ __metadata: languageName: node linkType: hard -"make-dir@npm:^2.0.0, make-dir@npm:^2.1.0": +"magic-string@npm:^0.25.0, magic-string@npm:^0.25.7": + version: 0.25.9 + resolution: "magic-string@npm:0.25.9" + dependencies: + sourcemap-codec: ^1.4.8 + checksum: 9a0e55a15c7303fc360f9572a71cffba1f61451bc92c5602b1206c9d17f492403bf96f946dfce7483e66822d6b74607262e24392e87b0ac27b786e69a40e9b1a + languageName: node + linkType: hard + +"make-dir@npm:^2.0.0": version: 2.1.0 resolution: "make-dir@npm:2.1.0" dependencies: @@ -12199,6 +13114,15 @@ __metadata: languageName: node linkType: hard +"make-dir@npm:^4.0.0": + version: 4.0.0 + resolution: "make-dir@npm:4.0.0" + dependencies: + semver: ^7.5.3 + checksum: bf0731a2dd3aab4db6f3de1585cea0b746bb73eb5a02e3d8d72757e376e64e6ada190b1eddcde5b2f24a81b688a9897efd5018737d05e02e2a671dda9cff8a8a + languageName: node + linkType: hard + "make-fetch-happen@npm:^10.0.3": version: 10.0.5 resolution: "make-fetch-happen@npm:10.0.5" @@ -12280,13 +13204,6 @@ __metadata: languageName: node linkType: hard -"mamacro@npm:^0.0.3": - version: 0.0.3 - resolution: "mamacro@npm:0.0.3" - checksum: ed3f970007248e377cd3a141866e2d6ba0ef09344b4ed1d80dcce6b5d6cdec6a50675894cc5249efdefeace60dd430afcf4af6cbd6bf975d79feb9c4b703fbc2 - languageName: node - linkType: hard - "map-age-cleaner@npm:^0.1.1": version: 0.1.3 resolution: "map-age-cleaner@npm:0.1.3" @@ -12303,7 +13220,7 @@ __metadata: languageName: node linkType: hard -"map-obj@npm:^1.0.0, map-obj@npm:^1.0.1": +"map-obj@npm:^1.0.0": version: 1.0.1 resolution: "map-obj@npm:1.0.1" checksum: 9949e7baec2a336e63b8d4dc71018c117c3ce6e39d2451ccbfd3b8350c547c4f6af331a4cbe1c83193d7c6b786082b6256bde843db90cb7da2a21e8fcc28afed @@ -12422,24 +13339,6 @@ __metadata: languageName: node linkType: hard -"meow@npm:^3.7.0": - version: 3.7.0 - resolution: "meow@npm:3.7.0" - dependencies: - camelcase-keys: ^2.0.0 - decamelize: ^1.1.2 - loud-rejection: ^1.0.0 - map-obj: ^1.0.1 - minimist: ^1.1.3 - normalize-package-data: ^2.3.4 - object-assign: ^4.0.1 - read-pkg-up: ^1.0.1 - redent: ^1.0.0 - trim-newlines: ^1.0.0 - checksum: 65a412e5d0d643615508007a9292799bb3e4e690597d54c9e98eb0ca3adb7b8ca8899f41ea7cb7d8277129cdcd9a1a60202b31f88e0034e6aaae02894d80999a - languageName: node - linkType: hard - "meow@npm:^9.0.0": version: 9.0.0 resolution: "meow@npm:9.0.0" @@ -12460,17 +13359,6 @@ __metadata: languageName: node linkType: hard -"merge-deep@npm:^3.0.2": - version: 3.0.3 - resolution: "merge-deep@npm:3.0.3" - dependencies: - arr-union: ^3.1.0 - clone-deep: ^0.2.4 - kind-of: ^3.0.2 - checksum: d2eb367b8300327c66a3e1e01eb06251f51b440bf5bfa5f0f8065ae95bf3af620d21fcd0ab2eb50e74f5119aac40ffd26c85e3bf82f79082e8757675f5885d3d - languageName: node - linkType: hard - "merge-descriptors@npm:1.0.1": version: 1.0.1 resolution: "merge-descriptors@npm:1.0.1" @@ -12485,7 +13373,7 @@ __metadata: languageName: node linkType: hard -"merge2@npm:^1.2.3, merge2@npm:^1.3.0, merge2@npm:^1.4.1": +"merge2@npm:^1.3.0, merge2@npm:^1.4.1": version: 1.4.1 resolution: "merge2@npm:1.4.1" checksum: 7268db63ed5169466540b6fb947aec313200bcf6d40c5ab722c22e242f651994619bcd85601602972d3c85bd2cc45a358a4c61937e9f11a061919a1da569b0c2 @@ -12527,7 +13415,7 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.4": +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4, micromatch@npm:^4.0.5": version: 4.0.5 resolution: "micromatch@npm:4.0.5" dependencies: @@ -12572,7 +13460,7 @@ __metadata: languageName: node linkType: hard -"mime-types@npm:~2.1.34": +"mime-types@npm:^2.1.27, mime-types@npm:~2.1.34": version: 2.1.35 resolution: "mime-types@npm:2.1.35" dependencies: @@ -12629,17 +13517,17 @@ __metadata: languageName: node linkType: hard -"mini-css-extract-plugin@npm:0.9.0": - version: 0.9.0 - resolution: "mini-css-extract-plugin@npm:0.9.0" +"mini-css-extract-plugin@npm:0.11.3": + version: 0.11.3 + resolution: "mini-css-extract-plugin@npm:0.11.3" dependencies: loader-utils: ^1.1.0 normalize-url: 1.9.1 schema-utils: ^1.0.0 webpack-sources: ^1.1.0 peerDependencies: - webpack: ^4.4.0 - checksum: e5cf437c15e4adf119d3a5af1bb604c880bc90a637aaf0535c8db68219efec42dcace1c54789422dec05d76ced98c44ef89ae44a3c556e34936fdbdd4743a210 + webpack: ^4.4.0 || ^5.0.0 + checksum: 14fbdf1338fe0264a2f7f87b3fc640809b7443f6434c6532bdbec1c5ab113502325fec958e9cf0667c3790087dc1e83c02e1f4d7463c10c956b0d6ebe56ea99e languageName: node linkType: hard @@ -12666,7 +13554,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.4": +"minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -12704,7 +13592,7 @@ __metadata: languageName: node linkType: hard -"minimist@npm:^1.1.1, minimist@npm:^1.1.3, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.8": +"minimist@npm:^1.1.1, minimist@npm:^1.2.0, minimist@npm:^1.2.5, minimist@npm:^1.2.6, minimist@npm:^1.2.8": version: 1.2.8 resolution: "minimist@npm:1.2.8" checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0 @@ -12864,16 +13752,6 @@ __metadata: languageName: node linkType: hard -"mixin-object@npm:^2.0.1": - version: 2.0.1 - resolution: "mixin-object@npm:2.0.1" - dependencies: - for-in: ^0.1.3 - is-extendable: ^0.1.1 - checksum: 7d0eb7c2f06435fcc01d132824b4c973a0df689a117d8199d79911b506363b6f4f86a84458a63f3acfa7388f3052612cfe27105400b4932678452925a9739a4c - languageName: node - linkType: hard - "mkdirp@npm:>=0.5 0, mkdirp@npm:^0.5.1, mkdirp@npm:^0.5.3, mkdirp@npm:^0.5.5, mkdirp@npm:~0.5.1": version: 0.5.5 resolution: "mkdirp@npm:0.5.5" @@ -12962,14 +13840,7 @@ __metadata: languageName: node linkType: hard -"mute-stream@npm:0.0.8": - version: 0.0.8 - resolution: "mute-stream@npm:0.0.8" - checksum: ff48d251fc3f827e5b1206cda0ffdaec885e56057ee86a3155e1951bc940fd5f33531774b1cc8414d7668c10a8907f863f6561875ee6e8768931a62121a531a1 - languageName: node - linkType: hard - -"nan@npm:^2.12.1, nan@npm:^2.13.2": +"nan@npm:^2.12.1": version: 2.14.2 resolution: "nan@npm:2.14.2" dependencies: @@ -12987,7 +13858,7 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:^3.3.6": +"nanoid@npm:^3.3.6, nanoid@npm:^3.3.7": version: 3.3.7 resolution: "nanoid@npm:3.3.7" bin: @@ -13015,6 +13886,15 @@ __metadata: languageName: node linkType: hard +"native-url@npm:^0.2.6": + version: 0.2.6 + resolution: "native-url@npm:0.2.6" + dependencies: + querystring: ^0.2.0 + checksum: d56a67b32e635c4944985f551a9976dfe609a3947810791c50f5c37cff1d9dd5fe040184989d104be8752582b79dc4e726f2a9c075d691ecce86b31ae9387f1b + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -13213,23 +14093,24 @@ __metadata: languageName: node linkType: hard -"node-notifier@npm:^5.4.2": - version: 5.4.5 - resolution: "node-notifier@npm:5.4.5" +"node-notifier@npm:^8.0.0": + version: 8.0.2 + resolution: "node-notifier@npm:8.0.2" dependencies: growly: ^1.3.0 - is-wsl: ^1.1.0 - semver: ^5.5.0 + is-wsl: ^2.2.0 + semver: ^7.3.2 shellwords: ^0.1.1 - which: ^1.3.0 - checksum: 8de174eb055a2ec55c1b0beede9328e8f9d4e32e7eacb7e3e2fddff48534105d0e2e10b4947dd422cc0602c65141317499c6fb1dc3b8ba03c775fb159e360bef + uuid: ^8.3.0 + which: ^2.0.2 + checksum: 7db1683003f6aaa4324959dfa663cd56e301ccc0165977a9e7737989ffe3b4763297f9fc85f44d0662b63a4fd85516eda43411b492a4d2fae207afb23773f912 languageName: node linkType: hard -"node-releases@npm:^1.1.52": - version: 1.1.73 - resolution: "node-releases@npm:1.1.73" - checksum: 44a6caec3330538a669c156fa84833725ae92b317585b106e08ab292c14da09f30cb913c10f1a7402180a51b10074832d4e045b6c3512d74c37d86b41a69e63b +"node-releases@npm:^1.1.61": + version: 1.1.77 + resolution: "node-releases@npm:1.1.77" + checksum: eb2fcb45310e7d77f82bfdadeca546a698d258e011f15d88ad9a452a5e838a672ec532906581096ca19c66284a788330c3b09227ffc540e67228730f41b9c2e2 languageName: node linkType: hard @@ -13247,49 +14128,6 @@ __metadata: languageName: node linkType: hard -"node-sass-chokidar@npm:^2.0.0": - version: 2.0.0 - resolution: "node-sass-chokidar@npm:2.0.0" - dependencies: - async-foreach: ^0.1.3 - chokidar: ^3.4.0 - get-stdin: ^4.0.1 - glob: ^7.0.3 - meow: ^3.7.0 - node-sass: ^7.0.1 - sass-graph: ^2.2.4 - stdout-stream: ^1.4.0 - bin: - node-sass-chokidar: bin/node-sass-chokidar - checksum: 5aeffc93cddf5cc32d0e86de4999e56e3cdccb1d86b5ed211e2d661f4e579bac19c078ca791662e2aaff9752ba2e18ce87324c07de5b3222064a4c9703856d9c - languageName: node - linkType: hard - -"node-sass@npm:^7.0.1": - version: 7.0.3 - resolution: "node-sass@npm:7.0.3" - dependencies: - async-foreach: ^0.1.3 - chalk: ^4.1.2 - cross-spawn: ^7.0.3 - gaze: ^1.0.0 - get-stdin: ^4.0.1 - glob: ^7.0.3 - lodash: ^4.17.15 - meow: ^9.0.0 - nan: ^2.13.2 - node-gyp: ^8.4.1 - npmlog: ^5.0.0 - request: ^2.88.0 - sass-graph: ^4.0.1 - stdout-stream: ^1.4.0 - true-case-path: ^1.0.2 - bin: - node-sass: bin/node-sass - checksum: 7d577d0fb68948959f367341e6cfc2858aa37abc5fadbd9e6b477ed0d192bebf7f8516d0b53c27be30ab05d5cd62d8a9bab08cc4442ef901b02cb51d864b4419 - languageName: node - linkType: hard - "node-sass@npm:^9.0.0": version: 9.0.0 resolution: "node-sass@npm:9.0.0" @@ -13325,7 +14163,7 @@ __metadata: languageName: node linkType: hard -"normalize-package-data@npm:^2.3.2, normalize-package-data@npm:^2.3.4, normalize-package-data@npm:^2.5.0": +"normalize-package-data@npm:^2.5.0": version: 2.5.0 resolution: "normalize-package-data@npm:2.5.0" dependencies: @@ -13416,18 +14254,6 @@ __metadata: languageName: node linkType: hard -"npmlog@npm:^5.0.0": - version: 5.0.1 - resolution: "npmlog@npm:5.0.1" - dependencies: - are-we-there-yet: ^2.0.0 - console-control-strings: ^1.1.0 - gauge: ^3.0.0 - set-blocking: ^2.0.0 - checksum: 516b2663028761f062d13e8beb3f00069c5664925871a9b57989642ebe09f23ab02145bf3ab88da7866c4e112cafff72401f61a672c7c8a20edc585a7016ef5f - languageName: node - linkType: hard - "npmlog@npm:^6.0.0": version: 6.0.1 resolution: "npmlog@npm:6.0.1" @@ -13465,17 +14291,10 @@ __metadata: languageName: node linkType: hard -"number-is-nan@npm:^1.0.0": - version: 1.0.1 - resolution: "number-is-nan@npm:1.0.1" - checksum: 13656bc9aa771b96cef209ffca31c31a03b507ca6862ba7c3f638a283560620d723d52e626d57892c7fff475f4c36ac07f0600f14544692ff595abff214b9ffb - languageName: node - linkType: hard - -"nwsapi@npm:^2.0.7, nwsapi@npm:^2.1.3": - version: 2.2.0 - resolution: "nwsapi@npm:2.2.0" - checksum: 5ef4a9bc0c1a5b7f2e014aa6a4b359a257503b796618ed1ef0eb852098f77e772305bb0e92856e4bbfa3e6c75da48c0113505c76f144555ff38867229c2400a7 +"nwsapi@npm:^2.2.0": + version: 2.2.7 + resolution: "nwsapi@npm:2.2.7" + checksum: cab25f7983acec7e23490fec3ef7be608041b460504229770e3bfcf9977c41d6fe58f518994d3bd9aa3a101f501089a3d4a63536f4ff8ae4b8c4ca23bdbfda4e languageName: node linkType: hard @@ -13504,13 +14323,6 @@ __metadata: languageName: node linkType: hard -"object-hash@npm:^2.0.1": - version: 2.2.0 - resolution: "object-hash@npm:2.2.0" - checksum: 55ba841e3adce9c4f1b9b46b41983eda40f854e0d01af2802d3ae18a7085a17168d6b81731d43fdf1d6bcbb3c9f9c56d22c8fea992203ad90a38d7d919bc28f1 - languageName: node - linkType: hard - "object-inspect@npm:^1.10.3, object-inspect@npm:^1.7.0, object-inspect@npm:^1.9.0": version: 1.10.3 resolution: "object-inspect@npm:1.10.3" @@ -13518,6 +14330,13 @@ __metadata: languageName: node linkType: hard +"object-inspect@npm:^1.13.1": + version: 1.13.1 + resolution: "object-inspect@npm:1.13.1" + checksum: 7d9fa9221de3311dcb5c7c307ee5dc011cdd31dc43624b7c184b3840514e118e05ef0002be5388304c416c0eb592feb46e983db12577fc47e47d5752fbbfb61f + languageName: node + linkType: hard + "object-is@npm:^1.0.1, object-is@npm:^1.0.2, object-is@npm:^1.1.2": version: 1.1.5 resolution: "object-is@npm:1.1.5" @@ -13556,6 +14375,18 @@ __metadata: languageName: node linkType: hard +"object.assign@npm:^4.1.4, object.assign@npm:^4.1.5": + version: 4.1.5 + resolution: "object.assign@npm:4.1.5" + dependencies: + call-bind: ^1.0.5 + define-properties: ^1.2.1 + has-symbols: ^1.0.3 + object-keys: ^1.1.1 + checksum: f9aeac0541661370a1fc86e6a8065eb1668d3e771f7dbb33ee54578201336c057b21ee61207a186dd42db0c62201d91aac703d20d12a79fc79c353eed44d4e25 + languageName: node + linkType: hard + "object.entries@npm:^1.1.0, object.entries@npm:^1.1.1, object.entries@npm:^1.1.2": version: 1.1.4 resolution: "object.entries@npm:1.1.4" @@ -13567,7 +14398,18 @@ __metadata: languageName: node linkType: hard -"object.fromentries@npm:^2.0.2, object.fromentries@npm:^2.0.3": +"object.entries@npm:^1.1.7": + version: 1.1.8 + resolution: "object.entries@npm:1.1.8" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: 5314877cb637ef3437a30bba61d9bacdb3ce74bf73ac101518be0633c37840c8cc67407edb341f766e8093b3d7516d5c3358f25adfee4a2c697c0ec4c8491907 + languageName: node + linkType: hard + +"object.fromentries@npm:^2.0.3": version: 2.0.4 resolution: "object.fromentries@npm:2.0.4" dependencies: @@ -13579,7 +14421,19 @@ __metadata: languageName: node linkType: hard -"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.0, object.getownpropertydescriptors@npm:^2.1.1": +"object.fromentries@npm:^2.0.7": + version: 2.0.8 + resolution: "object.fromentries@npm:2.0.8" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-object-atoms: ^1.0.0 + checksum: 29b2207a2db2782d7ced83f93b3ff5d425f901945f3665ffda1821e30a7253cd1fd6b891a64279976098137ddfa883d748787a6fea53ecdb51f8df8b8cec0ae1 + languageName: node + linkType: hard + +"object.getownpropertydescriptors@npm:^2.0.3, object.getownpropertydescriptors@npm:^2.1.0": version: 2.1.2 resolution: "object.getownpropertydescriptors@npm:2.1.2" dependencies: @@ -13590,6 +14444,28 @@ __metadata: languageName: node linkType: hard +"object.groupby@npm:^1.0.1": + version: 1.0.3 + resolution: "object.groupby@npm:1.0.3" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + checksum: 0d30693ca3ace29720bffd20b3130451dca7a56c612e1926c0a1a15e4306061d84410bdb1456be2656c5aca53c81b7a3661eceaa362db1bba6669c2c9b6d1982 + languageName: node + linkType: hard + +"object.hasown@npm:^1.1.3": + version: 1.1.4 + resolution: "object.hasown@npm:1.1.4" + dependencies: + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-object-atoms: ^1.0.0 + checksum: bc46eb5ca22106fcd07aab1411508c2c68b7565fe8fb272f166fb9bf203972e8b5c86a5a4b2c86204beead0626a7a4119d32cefbaf7c5dd57b400bf9e6363cb6 + languageName: node + linkType: hard + "object.pick@npm:^1.3.0": version: 1.3.0 resolution: "object.pick@npm:1.3.0" @@ -13610,6 +14486,17 @@ __metadata: languageName: node linkType: hard +"object.values@npm:^1.1.6, object.values@npm:^1.1.7": + version: 1.2.0 + resolution: "object.values@npm:1.2.0" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: 51fef456c2a544275cb1766897f34ded968b22adfc13ba13b5e4815fdaf4304a90d42a3aee114b1f1ede048a4890381d47a5594d84296f2767c6a0364b9da8fa + languageName: node + linkType: hard + "obuf@npm:^1.0.0, obuf@npm:^1.1.2": version: 1.1.2 resolution: "obuf@npm:1.1.2" @@ -13670,19 +14557,19 @@ __metadata: languageName: node linkType: hard -"optimize-css-assets-webpack-plugin@npm:5.0.3": - version: 5.0.3 - resolution: "optimize-css-assets-webpack-plugin@npm:5.0.3" +"optimize-css-assets-webpack-plugin@npm:5.0.4": + version: 5.0.4 + resolution: "optimize-css-assets-webpack-plugin@npm:5.0.4" dependencies: cssnano: ^4.1.10 last-call-webpack-plugin: ^3.0.0 peerDependencies: webpack: ^4.0.0 - checksum: 334eb9cb83643bba259946034d15ab123fd503d646f07edd1731efe57cf1c086c4fe28f804da8171316bbfa175c5f24913ae4337059045785cf7dacac303228d + checksum: bcd509eaab2a6f0ed8396fe847f4f0da73655a54f4c418fa30dc1fc4a0b1b620f38e2fcd6bcb369e2a6cf4530995b371e9d12011566ac7ffe6ac6aec2ab0a4fb languageName: node linkType: hard -"optionator@npm:^0.8.1, optionator@npm:^0.8.3": +"optionator@npm:^0.8.1": version: 0.8.3 resolution: "optionator@npm:0.8.3" dependencies: @@ -13696,26 +14583,24 @@ __metadata: languageName: node linkType: hard -"os-browserify@npm:^0.3.0": - version: 0.3.0 - resolution: "os-browserify@npm:0.3.0" - checksum: 16e37ba3c0e6a4c63443c7b55799ce4066d59104143cb637ecb9fce586d5da319cdca786ba1c867abbe3890d2cbf37953f2d51eea85e20dd6c4570d6c54bfebf - languageName: node - linkType: hard - -"os-locale@npm:^1.4.0": - version: 1.4.0 - resolution: "os-locale@npm:1.4.0" +"optionator@npm:^0.9.1": + version: 0.9.3 + resolution: "optionator@npm:0.9.3" dependencies: - lcid: ^1.0.0 - checksum: 0161a1b6b5a8492f99f4b47fe465df9fc521c55ba5414fce6444c45e2500487b8ed5b40a47a98a2363fe83ff04ab033785300ed8df717255ec4c3b625e55b1fb + "@aashutoshrathi/word-wrap": ^1.2.3 + deep-is: ^0.1.3 + fast-levenshtein: ^2.0.6 + levn: ^0.4.1 + prelude-ls: ^1.2.1 + type-check: ^0.4.0 + checksum: 09281999441f2fe9c33a5eeab76700795365a061563d66b098923eb719251a42bdbe432790d35064d0816ead9296dbeb1ad51a733edf4167c96bd5d0882e428a languageName: node linkType: hard -"os-tmpdir@npm:~1.0.2": - version: 1.0.2 - resolution: "os-tmpdir@npm:1.0.2" - checksum: 5666560f7b9f10182548bf7013883265be33620b1c1b4a4d405c25be2636f970c5488ff3e6c48de75b55d02bde037249fe5dbfbb4c0fb7714953d56aed062e6d +"os-browserify@npm:^0.3.0": + version: 0.3.0 + resolution: "os-browserify@npm:0.3.0" + checksum: 16e37ba3c0e6a4c63443c7b55799ce4066d59104143cb637ecb9fce586d5da319cdca786ba1c867abbe3890d2cbf37953f2d51eea85e20dd6c4570d6c54bfebf languageName: node linkType: hard @@ -13733,12 +14618,10 @@ __metadata: languageName: node linkType: hard -"p-each-series@npm:^1.0.0": - version: 1.0.0 - resolution: "p-each-series@npm:1.0.0" - dependencies: - p-reduce: ^1.0.0 - checksum: 5acdaedd36e0c7b9617f4924dccfd681cbe4dd9f98b0eb0fde7c00dc701eeceaba55c0dc1dfde13207bdab3715a4c5040d806d7ddc493f27498110bdc1e9dd5d +"p-each-series@npm:^2.1.0": + version: 2.2.0 + resolution: "p-each-series@npm:2.2.0" + checksum: 5fbe2f1f1966f55833bd401fe36f7afe410707d5e9fb6032c6dde8aa716d50521c3bb201fdb584130569b5941d5e84993e09e0b3f76a474288e0ede8f632983c languageName: node linkType: hard @@ -13751,21 +14634,12 @@ __metadata: "p-is-promise@npm:^1.1.0": version: 1.1.0 - resolution: "p-is-promise@npm:1.1.0" - checksum: 64d7c6cda18af2c91c04209e5856c54d1a9818662d2320b34153d446645f431307e04406969a1be00cad680288e86dcf97b9eb39edd5dc4d0b1bd714ee85e13b - languageName: node - linkType: hard - -"p-limit@npm:^1.1.0": - version: 1.3.0 - resolution: "p-limit@npm:1.3.0" - dependencies: - p-try: ^1.0.0 - checksum: 281c1c0b8c82e1ac9f81acd72a2e35d402bf572e09721ce5520164e9de07d8274451378a3470707179ad13240535558f4b277f02405ad752e08c7d5b0d54fbfd + resolution: "p-is-promise@npm:1.1.0" + checksum: 64d7c6cda18af2c91c04209e5856c54d1a9818662d2320b34153d446645f431307e04406969a1be00cad680288e86dcf97b9eb39edd5dc4d0b1bd714ee85e13b languageName: node linkType: hard -"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0, p-limit@npm:^2.3.0": +"p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" dependencies: @@ -13774,12 +14648,12 @@ __metadata: languageName: node linkType: hard -"p-locate@npm:^2.0.0": - version: 2.0.0 - resolution: "p-locate@npm:2.0.0" +"p-limit@npm:^3.0.2": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" dependencies: - p-limit: ^1.1.0 - checksum: e2dceb9b49b96d5513d90f715780f6f4972f46987dc32a0e18bc6c3fc74a1a5d73ec5f81b1398af5e58b99ea1ad03fd41e9181c01fa81b4af2833958696e3081 + yocto-queue: ^0.1.0 + checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 languageName: node linkType: hard @@ -13808,15 +14682,6 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^3.0.0": - version: 3.0.0 - resolution: "p-map@npm:3.0.0" - dependencies: - aggregate-error: ^3.0.0 - checksum: 49b0fcbc66b1ef9cd379de1b4da07fa7a9f84b41509ea3f461c31903623aaba8a529d22f835e0d77c7cb9fcc16e4fae71e308fd40179aea514ba68f27032b5d5 - languageName: node - linkType: hard - "p-map@npm:^4.0.0": version: 4.0.0 resolution: "p-map@npm:4.0.0" @@ -13826,13 +14691,6 @@ __metadata: languageName: node linkType: hard -"p-reduce@npm:^1.0.0": - version: 1.0.0 - resolution: "p-reduce@npm:1.0.0" - checksum: 7b0f25c861ca2319c1fd6d28d1421edca12eb5b780b2f2bcdb418e634b4c2ef07bd85f75ad41594474ec512e5505b49c36e7b22a177d43c60cc014576eab8888 - languageName: node - linkType: hard - "p-retry@npm:^3.0.1": version: 3.0.1 resolution: "p-retry@npm:3.0.1" @@ -13842,13 +14700,6 @@ __metadata: languageName: node linkType: hard -"p-try@npm:^1.0.0": - version: 1.0.0 - resolution: "p-try@npm:1.0.0" - checksum: 3b5303f77eb7722144154288bfd96f799f8ff3e2b2b39330efe38db5dd359e4fb27012464cd85cb0a76e9b7edd1b443568cb3192c22e7cffc34989df0bafd605 - languageName: node - linkType: hard - "p-try@npm:^2.0.0": version: 2.2.0 resolution: "p-try@npm:2.2.0" @@ -13927,15 +14778,6 @@ __metadata: languageName: node linkType: hard -"parse-json@npm:^2.2.0": - version: 2.2.0 - resolution: "parse-json@npm:2.2.0" - dependencies: - error-ex: ^1.2.0 - checksum: dda78a63e57a47b713a038630868538f718a7ca0cd172a36887b0392ccf544ed0374902eb28f8bf3409e8b71d62b79d17062f8543afccf2745f9b0b2d2bb80ca - languageName: node - linkType: hard - "parse-json@npm:^4.0.0": version: 4.0.0 resolution: "parse-json@npm:4.0.0" @@ -13967,21 +14809,7 @@ __metadata: languageName: node linkType: hard -"parse5@npm:4.0.0": - version: 4.0.0 - resolution: "parse5@npm:4.0.0" - checksum: 2123cec690689fed44e6c76aa8a08215d2dadece7eff7b35156dda7485e6a232c9b737313688ee715eb0678b6a87a31026927dd74690154f8a0811059845ba46 - languageName: node - linkType: hard - -"parse5@npm:5.1.0": - version: 5.1.0 - resolution: "parse5@npm:5.1.0" - checksum: 13c44c6d47035a3cc75303655ae5630dc264f9b9ab8344feb3f79ca195d8b57a2a246af902abef1d780ad1eee92eb9b88cd03098a7ee7dd111f032152ebaf0a6 - languageName: node - linkType: hard - -"parse5@npm:^6.0.1": +"parse5@npm:6.0.1, parse5@npm:^6.0.1": version: 6.0.1 resolution: "parse5@npm:6.0.1" checksum: 7d569a176c5460897f7c8f3377eff640d54132b9be51ae8a8fa4979af940830b2b0c296ce75e5bd8f4041520aadde13170dbdec44889975f906098ea0002f4bd @@ -14026,15 +14854,6 @@ __metadata: languageName: node linkType: hard -"path-exists@npm:^2.0.0": - version: 2.1.0 - resolution: "path-exists@npm:2.1.0" - dependencies: - pinkie-promise: ^2.0.0 - checksum: fdb734f1d00f225f7a0033ce6d73bff6a7f76ea08936abf0e5196fa6e54a645103538cd8aedcb90d6d8c3fa3705ded0c58a4da5948ae92aa8834892c1ab44a84 - languageName: node - linkType: hard - "path-exists@npm:^3.0.0": version: 3.0.0 resolution: "path-exists@npm:3.0.0" @@ -14077,7 +14896,7 @@ __metadata: languageName: node linkType: hard -"path-parse@npm:^1.0.6": +"path-parse@npm:^1.0.6, path-parse@npm:^1.0.7": version: 1.0.7 resolution: "path-parse@npm:1.0.7" checksum: 49abf3d81115642938a8700ec580da6e830dde670be21893c62f4e10bd7dd4c3742ddc603fe24f898cba7eb0c6bc1777f8d9ac14185d34540c6d4d80cd9cae8a @@ -14100,35 +14919,6 @@ __metadata: languageName: node linkType: hard -"path-type@npm:^1.0.0": - version: 1.1.0 - resolution: "path-type@npm:1.1.0" - dependencies: - graceful-fs: ^4.1.2 - pify: ^2.0.0 - pinkie-promise: ^2.0.0 - checksum: 59a4b2c0e566baf4db3021a1ed4ec09a8b36fca960a490b54a6bcefdb9987dafe772852982b6011cd09579478a96e57960a01f75fa78a794192853c9d468fc79 - languageName: node - linkType: hard - -"path-type@npm:^2.0.0": - version: 2.0.0 - resolution: "path-type@npm:2.0.0" - dependencies: - pify: ^2.0.0 - checksum: 749dc0c32d4ebe409da155a0022f9be3d08e6fd276adb3dfa27cb2486519ab2aa277d1453b3fde050831e0787e07b0885a75653fefcc82d883753c5b91121b1c - languageName: node - linkType: hard - -"path-type@npm:^3.0.0": - version: 3.0.0 - resolution: "path-type@npm:3.0.0" - dependencies: - pify: ^3.0.0 - checksum: 735b35e256bad181f38fa021033b1c33cfbe62ead42bb2222b56c210e42938eecb272ae1949f3b6db4ac39597a61b44edd8384623ec4d79bfdc9a9c0f12537a6 - languageName: node - linkType: hard - "path-type@npm:^4.0.0": version: 4.0.0 resolution: "path-type@npm:4.0.0" @@ -14184,7 +14974,7 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^2.3.1": +"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" checksum: 050c865ce81119c4822c45d3c84f1ced46f93a0126febae20737bd05ca20589c564d6e9226977df859ed5e03dc73f02584a2b0faad36e896936238238b0446cf @@ -14198,13 +14988,6 @@ __metadata: languageName: node linkType: hard -"pify@npm:^3.0.0": - version: 3.0.0 - resolution: "pify@npm:3.0.0" - checksum: 6cdcbc3567d5c412450c53261a3f10991665d660961e06605decf4544a61a97a54fefe70a68d5c37080ff9d6f4cf51444c90198d1ba9f9309a6c0d6e9f5c4fde - languageName: node - linkType: hard - "pify@npm:^4.0.1": version: 4.0.1 resolution: "pify@npm:4.0.1" @@ -14237,24 +15020,6 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^1.0.0": - version: 1.0.0 - resolution: "pkg-dir@npm:1.0.0" - dependencies: - find-up: ^1.0.0 - checksum: ce49878797dd81a5cee1cb7f05fdd431729309e4854c9f83d7748491b9d25c5f8ef04b3b7658134361fa036934c0aaa7fc7f984e46970dd227aa490f3869d36a - languageName: node - linkType: hard - -"pkg-dir@npm:^2.0.0": - version: 2.0.0 - resolution: "pkg-dir@npm:2.0.0" - dependencies: - find-up: ^2.1.0 - checksum: 8c72b712305b51e1108f0ffda5ec1525a8307e54a5855db8fb1dcf77561a5ae98e2ba3b4814c9806a679f76b2f7e5dd98bde18d07e594ddd9fdd25e9cf242ea1 - languageName: node - linkType: hard - "pkg-dir@npm:^3.0.0": version: 3.0.0 resolution: "pkg-dir@npm:3.0.0" @@ -14264,7 +15029,7 @@ __metadata: languageName: node linkType: hard -"pkg-dir@npm:^4.1.0": +"pkg-dir@npm:^4.1.0, pkg-dir@npm:^4.2.0": version: 4.2.0 resolution: "pkg-dir@npm:4.2.0" dependencies: @@ -14273,7 +15038,7 @@ __metadata: languageName: node linkType: hard -"pkg-up@npm:3.1.0, pkg-up@npm:^3.1.0": +"pkg-up@npm:3.1.0": version: 3.1.0 resolution: "pkg-up@npm:3.1.0" dependencies: @@ -14282,13 +15047,6 @@ __metadata: languageName: node linkType: hard -"pn@npm:^1.1.0": - version: 1.1.0 - resolution: "pn@npm:1.1.0" - checksum: e4654186dc92a187c8c7fe4ccda902f4d39dd9c10f98d1c5a08ce5fad5507ef1e33ddb091240c3950bee81bd201b4c55098604c433a33b5e8bdd97f38b732fa0 - languageName: node - linkType: hard - "pnp-webpack-plugin@npm:1.6.4": version: 1.6.4 resolution: "pnp-webpack-plugin@npm:1.6.4" @@ -14323,6 +15081,13 @@ __metadata: languageName: node linkType: hard +"possible-typed-array-names@npm:^1.0.0": + version: 1.0.0 + resolution: "possible-typed-array-names@npm:1.0.0" + checksum: b32d403ece71e042385cc7856385cecf1cd8e144fa74d2f1de40d1e16035dba097bc189715925e79b67bdd1472796ff168d3a90d296356c9c94d272d5b95f3ae + languageName: node + linkType: hard + "postcss-attribute-case-insensitive@npm:^4.0.1": version: 4.0.2 resolution: "postcss-attribute-case-insensitive@npm:4.0.2" @@ -14536,12 +15301,12 @@ __metadata: languageName: node linkType: hard -"postcss-flexbugs-fixes@npm:4.1.0": - version: 4.1.0 - resolution: "postcss-flexbugs-fixes@npm:4.1.0" +"postcss-flexbugs-fixes@npm:4.2.1": + version: 4.2.1 + resolution: "postcss-flexbugs-fixes@npm:4.2.1" dependencies: - postcss: ^7.0.0 - checksum: b5f2c39f4315a0eacfc23cafe6d20cff36e4605d266aa38f261e1db7f65e913e5fe3044d952d9435850f67525d5b1c7cc22eb6edeb51e19657c7a9a53b361dc5 + postcss: ^7.0.26 + checksum: 51a626bc80dbe42fcc8b0895b4f23a558bb809ec52cdc05aa27fb24cdffd4c9dc53f25218085ddf407c53d76573bc6d7568219c912161609f02532a8f5f59b43 languageName: node linkType: hard @@ -14734,7 +15499,7 @@ __metadata: languageName: node linkType: hard -"postcss-modules-local-by-default@npm:^3.0.2": +"postcss-modules-local-by-default@npm:^3.0.3": version: 3.0.3 resolution: "postcss-modules-local-by-default@npm:3.0.3" dependencies: @@ -14746,7 +15511,7 @@ __metadata: languageName: node linkType: hard -"postcss-modules-scope@npm:^2.1.1": +"postcss-modules-scope@npm:^2.2.0": version: 2.2.0 resolution: "postcss-modules-scope@npm:2.2.0" dependencies: @@ -15014,12 +15779,12 @@ __metadata: languageName: node linkType: hard -"postcss-safe-parser@npm:4.0.1": - version: 4.0.1 - resolution: "postcss-safe-parser@npm:4.0.1" +"postcss-safe-parser@npm:5.0.2": + version: 5.0.2 + resolution: "postcss-safe-parser@npm:5.0.2" dependencies: - postcss: ^7.0.0 - checksum: e4db1e5153521cfa77c046ea5c2600605339148c1ed039c61e8acea37e74ceea245f4ec4047bcea7782a34866a9c4b1321981c35374f211c292e8648e2ac4e33 + postcss: ^8.1.0 + checksum: b786eca091f856f2d31856d903c24c1b591ecbc0b607af0824e1cf12b9b254b5e1f24bc842cc2b95bc561f097d8b358fb4c9e04c73c1ba9c118d21bde9a83253 languageName: node linkType: hard @@ -15132,14 +15897,14 @@ __metadata: languageName: node linkType: hard -"postcss@npm:7.0.21": - version: 7.0.21 - resolution: "postcss@npm:7.0.21" +"postcss@npm:7.0.36": + version: 7.0.36 + resolution: "postcss@npm:7.0.36" dependencies: chalk: ^2.4.2 source-map: ^0.6.1 supports-color: ^6.1.0 - checksum: 5c11d58a4ffd54ddaf2f2f18ef7be10fc44405559ee56b52e41db8305d1b184d162138994dcce506ab77eef7283887a72d1b81cd1036c7fee106f50af0ef86d3 + checksum: 4cfc0989b9ad5d0e8971af80d87f9c5beac5c84cb89ff22ad69852edf73c0a2fa348e7e0a135b5897bf893edad0fe86c428769050431ad9b532f072ff530828d languageName: node linkType: hard @@ -15154,7 +15919,7 @@ __metadata: languageName: node linkType: hard -"postcss@npm:^7, postcss@npm:^7.0.0, postcss@npm:^7.0.1, postcss@npm:^7.0.14, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.23, postcss@npm:^7.0.27, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6": +"postcss@npm:^7, postcss@npm:^7.0.0, postcss@npm:^7.0.1, postcss@npm:^7.0.14, postcss@npm:^7.0.17, postcss@npm:^7.0.2, postcss@npm:^7.0.26, postcss@npm:^7.0.27, postcss@npm:^7.0.32, postcss@npm:^7.0.5, postcss@npm:^7.0.6": version: 7.0.39 resolution: "postcss@npm:7.0.39" dependencies: @@ -15164,6 +15929,24 @@ __metadata: languageName: node linkType: hard +"postcss@npm:^8.1.0": + version: 8.4.38 + resolution: "postcss@npm:8.4.38" + dependencies: + nanoid: ^3.3.7 + picocolors: ^1.0.0 + source-map-js: ^1.2.0 + checksum: 649f9e60a763ca4b5a7bbec446a069edf07f057f6d780a5a0070576b841538d1ecf7dd888f2fbfd1f76200e26c969e405aeeae66332e6927dbdc8bdcb90b9451 + languageName: node + linkType: hard + +"prelude-ls@npm:^1.2.1": + version: 1.2.1 + resolution: "prelude-ls@npm:1.2.1" + checksum: cd192ec0d0a8e4c6da3bb80e4f62afe336df3f76271ac6deb0e6a36187133b6073a19e9727a1ff108cd8b9982e4768850d413baa71214dd80c7979617dca827a + languageName: node + linkType: hard + "prelude-ls@npm:~1.1.2": version: 1.1.2 resolution: "prelude-ls@npm:1.1.2" @@ -15178,7 +15961,7 @@ __metadata: languageName: node linkType: hard -"pretty-bytes@npm:^5.1.0, pretty-bytes@npm:^5.6.0": +"pretty-bytes@npm:^5.3.0, pretty-bytes@npm:^5.6.0": version: 5.6.0 resolution: "pretty-bytes@npm:5.6.0" checksum: 9c082500d1e93434b5b291bd651662936b8bd6204ec9fa17d563116a192d6d86b98f6d328526b4e8d783c07d5499e2614a807520249692da9ec81564b2f439cd @@ -15195,19 +15978,7 @@ __metadata: languageName: node linkType: hard -"pretty-format@npm:^24.9.0": - version: 24.9.0 - resolution: "pretty-format@npm:24.9.0" - dependencies: - "@jest/types": ^24.9.0 - ansi-regex: ^4.0.0 - ansi-styles: ^3.2.0 - react-is: ^16.8.4 - checksum: ba9291c8dafd50d2fea1fbad5d2863a6f94e0c8835cce9778ec03bc11bb0f52b9ed0e4ee56aaa331d022ccae2fe52b92f73465a0af58fd0edb59deb6391c6847 - languageName: node - linkType: hard - -"pretty-format@npm:^26.0.0, pretty-format@npm:^26.6.2": +"pretty-format@npm:^26.0.0, pretty-format@npm:^26.6.0, pretty-format@npm:^26.6.2": version: 26.6.2 resolution: "pretty-format@npm:26.6.2" dependencies: @@ -15266,12 +16037,22 @@ __metadata: languageName: node linkType: hard -"promise@npm:^8.0.3": - version: 8.1.0 - resolution: "promise@npm:8.1.0" +"promise@npm:^8.1.0": + version: 8.3.0 + resolution: "promise@npm:8.3.0" dependencies: asap: ~2.0.6 - checksum: 89b71a56154ed7d66a73236d8e8351a9c59adddba3929ecc845f75421ff37fc08ea0c67ad76cd5c0b0d81812c7d07a32bed27e7df5fcc960c6d68b0c1cd771f7 + checksum: a69f0ddbddf78ffc529cffee7ad950d307347615970564b17988ce43fbe767af5c738a9439660b24a9a8cbea106c0dcbb6c2b20e23b7e96a8e89e5c2679e94d5 + languageName: node + linkType: hard + +"prompts@npm:2.4.0": + version: 2.4.0 + resolution: "prompts@npm:2.4.0" + dependencies: + kleur: ^3.0.3 + sisteransi: ^1.0.5 + checksum: 96c7bef8eb3c0bb2076d2bc5ee473f06e6d8ac01ac4d0f378dfeb0ddaf2f31c339360ec8f0f8486f78601d16ebef7c6bd9886d44b937ba01bab568b937190265 languageName: node linkType: hard @@ -15307,7 +16088,7 @@ __metadata: languageName: node linkType: hard -"prop-types@npm:^15.5.6": +"prop-types@npm:^15.5.6, prop-types@npm:^15.8.1": version: 15.8.1 resolution: "prop-types@npm:15.8.1" dependencies: @@ -15335,6 +16116,13 @@ __metadata: languageName: node linkType: hard +"proxy-from-env@npm:^1.1.0": + version: 1.1.0 + resolution: "proxy-from-env@npm:1.1.0" + checksum: ed7fcc2ba0a33404958e34d95d18638249a68c430e30fcb6c478497d72739ba64ce9810a24f53a7d921d0c065e5b78e3822759800698167256b04659366ca4d4 + languageName: node + linkType: hard + "prr@npm:~1.0.1": version: 1.0.1 resolution: "prr@npm:1.0.1" @@ -15489,6 +16277,13 @@ __metadata: languageName: node linkType: hard +"querystring@npm:^0.2.0": + version: 0.2.1 + resolution: "querystring@npm:0.2.1" + checksum: 7b83b45d641e75fd39cd6625ddfd44e7618e741c61e95281b57bbae8fde0afcc12cf851924559e5cc1ef9baa3b1e06e22b164ea1397d65dd94b801f678d9c8ce + languageName: node + linkType: hard + "querystringify@npm:^2.1.1": version: 2.2.0 resolution: "querystringify@npm:2.2.0" @@ -15574,17 +16369,17 @@ __metadata: languageName: node linkType: hard -"react-app-polyfill@npm:^1.0.6": - version: 1.0.6 - resolution: "react-app-polyfill@npm:1.0.6" +"react-app-polyfill@npm:^2.0.0": + version: 2.0.0 + resolution: "react-app-polyfill@npm:2.0.0" dependencies: - core-js: ^3.5.0 + core-js: ^3.6.5 object-assign: ^4.1.1 - promise: ^8.0.3 + promise: ^8.1.0 raf: ^3.4.1 - regenerator-runtime: ^0.13.3 - whatwg-fetch: ^3.0.0 - checksum: d38fb0e5f773eb618e39832e78e34b2382a33a2f633ecbc7aba3af819134938f25f4b6915f40dcbb46efa1096efdfabe44030165142000dcf522f564db7cb3b9 + regenerator-runtime: ^0.13.7 + whatwg-fetch: ^3.4.1 + checksum: 99e52a6b2229c7ca730cfd44ac95640f955be71d144225bd6c24fa47922a742658a371d0a2f0876d732533f1055b7cd7e9d534c89c29f8ca889ecd1b8d15f065 languageName: node linkType: hard @@ -15600,35 +16395,35 @@ __metadata: languageName: node linkType: hard -"react-dev-utils@npm:^10.2.1": - version: 10.2.1 - resolution: "react-dev-utils@npm:10.2.1" +"react-dev-utils@npm:^11.0.1": + version: 11.0.4 + resolution: "react-dev-utils@npm:11.0.4" dependencies: - "@babel/code-frame": 7.8.3 + "@babel/code-frame": 7.10.4 address: 1.1.2 - browserslist: 4.10.0 + browserslist: 4.14.2 chalk: 2.4.2 - cross-spawn: 7.0.1 + cross-spawn: 7.0.3 detect-port-alt: 1.1.6 escape-string-regexp: 2.0.0 - filesize: 6.0.1 + filesize: 6.1.0 find-up: 4.1.0 - fork-ts-checker-webpack-plugin: 3.1.1 + fork-ts-checker-webpack-plugin: 4.1.6 global-modules: 2.0.0 - globby: 8.0.2 + globby: 11.0.1 gzip-size: 5.1.1 - immer: 1.10.0 - inquirer: 7.0.4 + immer: 8.0.1 is-root: 2.1.0 - loader-utils: 1.2.3 + loader-utils: 2.0.0 open: ^7.0.2 pkg-up: 3.1.0 - react-error-overlay: ^6.0.7 + prompts: 2.4.0 + react-error-overlay: ^6.0.9 recursive-readdir: 2.2.2 shell-quote: 1.7.2 strip-ansi: 6.0.0 text-table: 0.2.0 - checksum: af58950075c69d5b179b5d527d59fe7072b18258042c412665a4e7425b796a4af24456e05b93ff837bdeec84746cd7d9ed9dce2119a8d57139b8ff71a6053dfc + checksum: b41c95010a4fb60d4ea6309423520e6268757b68df34de7e9e8dbc72549236a1f5a698ff99ad72a034ac51b042aa79ee53994330ce4df05bf867e63c5464bb3f languageName: node linkType: hard @@ -15686,10 +16481,10 @@ __metadata: languageName: node linkType: hard -"react-error-overlay@npm:^6.0.7": - version: 6.0.9 - resolution: "react-error-overlay@npm:6.0.9" - checksum: 695853bc885e798008a00c10d8d94e5ac91626e8130802fea37345f9c037f41b80104345db2ee87f225feb4a4ef71b0df572b17c378a6d397b6815f6d4a84293 +"react-error-overlay@npm:^6.0.9": + version: 6.0.11 + resolution: "react-error-overlay@npm:6.0.11" + checksum: ce7b44c38fadba9cedd7c095cf39192e632daeccf1d0747292ed524f17dcb056d16bc197ddee5723f9dd888f0b9b19c3b486c430319e30504289b9296f2d2c42 languageName: node linkType: hard @@ -15730,7 +16525,7 @@ __metadata: languageName: node linkType: hard -"react-is@npm:^16.13.1, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.1, react-is@npm:^16.8.4, react-is@npm:^16.8.6": +"react-is@npm:^16.13.1, react-is@npm:^16.6.3, react-is@npm:^16.7.0, react-is@npm:^16.8.1, react-is@npm:^16.8.6": version: 16.13.1 resolution: "react-is@npm:16.13.1" checksum: f7a19ac3496de32ca9ae12aa030f00f14a3d45374f1ceca0af707c831b2a6098ef0d6bdae51bd437b0a306d7f01d4677fcc8de7c0d331eb47ad0f46130e53c5f @@ -15788,6 +16583,13 @@ __metadata: languageName: node linkType: hard +"react-refresh@npm:^0.8.3": + version: 0.8.3 + resolution: "react-refresh@npm:0.8.3" + checksum: 3cffe5a9cbac1c5d59bf74bf9fff43c987d87ef32098b9092ea94b6637377d86c08565b9374d9397f446b3fbcd95de986ec77220a16f979687cb39b7b89e2f91 + languageName: node + linkType: hard + "react-router-dom@npm:4.3.1": version: 4.3.1 resolution: "react-router-dom@npm:4.3.1" @@ -15855,63 +16657,69 @@ __metadata: languageName: node linkType: hard -"react-scripts@npm:3.4.4": - version: 3.4.4 - resolution: "react-scripts@npm:3.4.4" - dependencies: - "@babel/core": 7.9.0 - "@svgr/webpack": 4.3.3 - "@typescript-eslint/eslint-plugin": ^2.10.0 - "@typescript-eslint/parser": ^2.10.0 - babel-eslint: 10.1.0 - babel-jest: ^24.9.0 +"react-scripts@npm:4.0.1": + version: 4.0.1 + resolution: "react-scripts@npm:4.0.1" + dependencies: + "@babel/core": 7.12.3 + "@pmmmwh/react-refresh-webpack-plugin": 0.4.2 + "@svgr/webpack": 5.4.0 + "@typescript-eslint/eslint-plugin": ^4.5.0 + "@typescript-eslint/parser": ^4.5.0 + babel-eslint: ^10.1.0 + babel-jest: ^26.6.0 babel-loader: 8.1.0 - babel-plugin-named-asset-import: ^0.3.6 - babel-preset-react-app: ^9.1.2 - camelcase: ^5.3.1 + babel-plugin-named-asset-import: ^0.3.7 + babel-preset-react-app: ^10.0.0 + bfj: ^7.0.2 + camelcase: ^6.1.0 case-sensitive-paths-webpack-plugin: 2.3.0 - css-loader: 3.4.2 + css-loader: 4.3.0 dotenv: 8.2.0 dotenv-expand: 5.1.0 - eslint: ^6.6.0 - eslint-config-react-app: ^5.2.1 - eslint-loader: 3.0.3 - eslint-plugin-flowtype: 4.6.0 - eslint-plugin-import: 2.20.1 - eslint-plugin-jsx-a11y: 6.2.3 - eslint-plugin-react: 7.19.0 - eslint-plugin-react-hooks: ^1.6.1 - file-loader: 4.3.0 - fs-extra: ^8.1.0 - fsevents: 2.1.2 - html-webpack-plugin: 4.0.0-beta.11 + eslint: ^7.11.0 + eslint-config-react-app: ^6.0.0 + eslint-plugin-flowtype: ^5.2.0 + eslint-plugin-import: ^2.22.1 + eslint-plugin-jest: ^24.1.0 + eslint-plugin-jsx-a11y: ^6.3.1 + eslint-plugin-react: ^7.21.5 + eslint-plugin-react-hooks: ^4.2.0 + eslint-plugin-testing-library: ^3.9.2 + eslint-webpack-plugin: ^2.1.0 + file-loader: 6.1.1 + fs-extra: ^9.0.1 + fsevents: ^2.1.3 + html-webpack-plugin: 4.5.0 identity-obj-proxy: 3.0.0 - jest: 24.9.0 - jest-environment-jsdom-fourteen: 1.0.1 - jest-resolve: 24.9.0 - jest-watch-typeahead: 0.4.2 - mini-css-extract-plugin: 0.9.0 - optimize-css-assets-webpack-plugin: 5.0.3 + jest: 26.6.0 + jest-circus: 26.6.0 + jest-resolve: 26.6.0 + jest-watch-typeahead: 0.6.1 + mini-css-extract-plugin: 0.11.3 + optimize-css-assets-webpack-plugin: 5.0.4 pnp-webpack-plugin: 1.6.4 - postcss-flexbugs-fixes: 4.1.0 + postcss-flexbugs-fixes: 4.2.1 postcss-loader: 3.0.0 postcss-normalize: 8.0.1 postcss-preset-env: 6.7.0 - postcss-safe-parser: 4.0.1 - react-app-polyfill: ^1.0.6 - react-dev-utils: ^10.2.1 - resolve: 1.15.0 - resolve-url-loader: 3.1.2 + postcss-safe-parser: 5.0.2 + prompts: 2.4.0 + react-app-polyfill: ^2.0.0 + react-dev-utils: ^11.0.1 + react-refresh: ^0.8.3 + resolve: 1.18.1 + resolve-url-loader: ^3.1.2 sass-loader: 8.0.2 - semver: 6.3.0 - style-loader: 0.23.1 - terser-webpack-plugin: 2.3.8 - ts-pnp: 1.1.6 - url-loader: 2.3.0 - webpack: 4.42.0 + semver: 7.3.2 + style-loader: 1.3.0 + terser-webpack-plugin: 4.2.3 + ts-pnp: 1.2.0 + url-loader: 4.1.1 + webpack: 4.44.2 webpack-dev-server: 3.11.0 webpack-manifest-plugin: 2.2.0 - workbox-webpack-plugin: 4.3.1 + workbox-webpack-plugin: 5.1.4 peerDependencies: typescript: ^3.2.1 dependenciesMeta: @@ -15921,8 +16729,8 @@ __metadata: typescript: optional: true bin: - react-scripts: bin/react-scripts.js - checksum: a3ea2dfbecb595c471b23153c86fcd9da09093576f90646ca79e2653baaf209c1c5b73eeb4ed02f591e91e2505a6b963ec4de7f4ef76f2e52c73839d735dc680 + react-scripts: ./bin/react-scripts.js + checksum: 5f3d284c63c3649f175daa72f40be43cd33f539370225c395b31a3fc812d5cea26135a7796760a0f0701489e6212739c72b87e01ede716c815016f1295b20aaa languageName: node linkType: hard @@ -16025,36 +16833,6 @@ __metadata: languageName: node linkType: hard -"read-pkg-up@npm:^1.0.1": - version: 1.0.1 - resolution: "read-pkg-up@npm:1.0.1" - dependencies: - find-up: ^1.0.0 - read-pkg: ^1.0.0 - checksum: d18399a0f46e2da32beb2f041edd0cda49d2f2cc30195a05c759ef3ed9b5e6e19ba1ad1bae2362bdec8c6a9f2c3d18f4d5e8c369e808b03d498d5781cb9122c7 - languageName: node - linkType: hard - -"read-pkg-up@npm:^2.0.0": - version: 2.0.0 - resolution: "read-pkg-up@npm:2.0.0" - dependencies: - find-up: ^2.0.0 - read-pkg: ^2.0.0 - checksum: 22f9026fb72219ecd165f94f589461c70a88461dc7ea0d439a310ef2a5271ff176a4df4e5edfad087d8ac89b8553945eb209476b671e8ed081c990f30fc40b27 - languageName: node - linkType: hard - -"read-pkg-up@npm:^4.0.0": - version: 4.0.0 - resolution: "read-pkg-up@npm:4.0.0" - dependencies: - find-up: ^3.0.0 - read-pkg: ^3.0.0 - checksum: dd867d9a912707bc11340aebc91780be9f36f34ee1d27a5dafb8520e0cb6344138b80eb8bf8325bebf519d26ecf14cbf6190d9e5f765f0120da5ede4013f4d13 - languageName: node - linkType: hard - "read-pkg-up@npm:^7.0.1": version: 7.0.1 resolution: "read-pkg-up@npm:7.0.1" @@ -16066,39 +16844,6 @@ __metadata: languageName: node linkType: hard -"read-pkg@npm:^1.0.0": - version: 1.1.0 - resolution: "read-pkg@npm:1.1.0" - dependencies: - load-json-file: ^1.0.0 - normalize-package-data: ^2.3.2 - path-type: ^1.0.0 - checksum: a0f5d5e32227ec8e6a028dd5c5134eab229768dcb7a5d9a41a284ed28ad4b9284fecc47383dc1593b5694f4de603a7ffaee84b738956b9b77e0999567485a366 - languageName: node - linkType: hard - -"read-pkg@npm:^2.0.0": - version: 2.0.0 - resolution: "read-pkg@npm:2.0.0" - dependencies: - load-json-file: ^2.0.0 - normalize-package-data: ^2.3.2 - path-type: ^2.0.0 - checksum: 85c5bf35f2d96acdd756151ba83251831bb2b1040b7d96adce70b2cb119b5320417f34876de0929f2d06c67f3df33ef4636427df3533913876f9ef2487a6f48f - languageName: node - linkType: hard - -"read-pkg@npm:^3.0.0": - version: 3.0.0 - resolution: "read-pkg@npm:3.0.0" - dependencies: - load-json-file: ^4.0.0 - normalize-package-data: ^2.3.2 - path-type: ^3.0.0 - checksum: 398903ebae6c7e9965419a1062924436cc0b6f516c42c4679a90290d2f87448ed8f977e7aa2dbba4aa1ac09248628c43e493ac25b2bc76640e946035200e34c6 - languageName: node - linkType: hard - "read-pkg@npm:^5.2.0": version: 5.2.0 resolution: "read-pkg@npm:5.2.0" @@ -16172,15 +16917,6 @@ __metadata: languageName: node linkType: hard -"realpath-native@npm:^1.1.0": - version: 1.1.0 - resolution: "realpath-native@npm:1.1.0" - dependencies: - util.promisify: ^1.0.0 - checksum: 75ef0595dea6186384b785a9e0993c58ec604f8be2e39b602fec6d7837c7f770af4a4eb3c81f864a7d81c518a7167a6eaabbc7695b7a88c56e1ef04b91c1d586 - languageName: node - linkType: hard - "recompose@npm:0.28.0 - 0.30.0": version: 0.30.0 resolution: "recompose@npm:0.30.0" @@ -16238,16 +16974,6 @@ __metadata: languageName: node linkType: hard -"redent@npm:^1.0.0": - version: 1.0.0 - resolution: "redent@npm:1.0.0" - dependencies: - indent-string: ^2.1.0 - strip-indent: ^1.0.1 - checksum: 2bb8f76fda9c9f44e26620047b0ba9dd1834b0a80309d0badcc23fdcf7bb27a7ca74e66b683baa0d4b8cb5db787f11be086504036d63447976f409dd3e73fd7d - languageName: node - linkType: hard - "redent@npm:^3.0.0": version: 3.0.0 resolution: "redent@npm:3.0.0" @@ -16361,6 +17087,21 @@ __metadata: languageName: node linkType: hard +"reflect.getprototypeof@npm:^1.0.4": + version: 1.0.6 + resolution: "reflect.getprototypeof@npm:1.0.6" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.1 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + globalthis: ^1.0.3 + which-builtin-type: ^1.1.3 + checksum: 88e9e65a7eaa0bf8e9a8bbf8ac07571363bc333ba8b6769ed5e013e0042ed7c385e97fae9049510b3b5fe4b42472d8f32de9ce8ce84902bc4297d4bbe3777dba + languageName: node + linkType: hard + "reflect.ownkeys@npm:^0.2.0": version: 0.2.0 resolution: "reflect.ownkeys@npm:0.2.0" @@ -16368,16 +17109,16 @@ __metadata: languageName: node linkType: hard -"regenerate-unicode-properties@npm:^8.2.0": - version: 8.2.0 - resolution: "regenerate-unicode-properties@npm:8.2.0" +"regenerate-unicode-properties@npm:^10.1.0": + version: 10.1.1 + resolution: "regenerate-unicode-properties@npm:10.1.1" dependencies: - regenerate: ^1.4.0 - checksum: ee7db70ab25b95f2e3f39537089fc3eddba0b39fc9b982d6602f127996ce873d8c55584d5428486ca00dc0a85d174d943354943cd4a745cda475c8fe314b4f8a + regenerate: ^1.4.2 + checksum: b80958ef40f125275824c2c47d5081dfaefebd80bff26c76761e9236767c748a4a95a69c053fe29d2df881177f2ca85df4a71fe70a82360388b31159ef19adcf languageName: node linkType: hard -"regenerate@npm:^1.4.0": +"regenerate@npm:^1.4.2": version: 1.4.2 resolution: "regenerate@npm:1.4.2" checksum: 3317a09b2f802da8db09aa276e469b57a6c0dd818347e05b8862959c6193408242f150db5de83c12c3fa99091ad95fb42a6db2c3329bfaa12a0ea4cbbeb30cb0 @@ -16398,13 +17139,20 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.13.3, regenerator-runtime@npm:^0.13.4": +"regenerator-runtime@npm:^0.13.4": version: 0.13.7 resolution: "regenerator-runtime@npm:0.13.7" checksum: 52b66e6669152c0b1bccd95c8e11aabbfe67bb97bdf00e223bdf723b0f0052d4da5c02001d4c4bef576bdc5bcdc38a20496d1b5363b65c950c8434ed5071d9e0 languageName: node linkType: hard +"regenerator-runtime@npm:^0.13.7": + version: 0.13.11 + resolution: "regenerator-runtime@npm:0.13.11" + checksum: 27481628d22a1c4e3ff551096a683b424242a216fee44685467307f14d58020af1e19660bf2e26064de946bad7eff28950eae9f8209d55723e2d9351e632bbb4 + languageName: node + linkType: hard + "regenerator-runtime@npm:^0.14.0": version: 0.14.1 resolution: "regenerator-runtime@npm:0.14.1" @@ -16412,12 +17160,12 @@ __metadata: languageName: node linkType: hard -"regenerator-transform@npm:^0.14.2": - version: 0.14.5 - resolution: "regenerator-transform@npm:0.14.5" +"regenerator-transform@npm:^0.15.2": + version: 0.15.2 + resolution: "regenerator-transform@npm:0.15.2" dependencies: "@babel/runtime": ^7.8.4 - checksum: a467a3b652b4ec26ff964e9c5f1817523a73fc44cb928b8d21ff11aebeac5d10a84d297fe02cea9f282bcec81a0b0d562237da69ef0f40a0160b30a4fa98bc94 + checksum: 20b6f9377d65954980fe044cfdd160de98df415b4bff38fbade67b3337efaf078308c4fed943067cd759827cc8cfeca9cb28ccda1f08333b85d6a2acbd022c27 languageName: node linkType: hard @@ -16438,7 +17186,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.2.0, regexp.prototype.flags@npm:^1.3.1": +"regexp.prototype.flags@npm:^1.2.0": version: 1.3.1 resolution: "regexp.prototype.flags@npm:1.3.1" dependencies: @@ -16448,10 +17196,15 @@ __metadata: languageName: node linkType: hard -"regexpp@npm:^2.0.1": - version: 2.0.1 - resolution: "regexpp@npm:2.0.1" - checksum: 1f41cf80ac08514c6665812e3dcc0673569431d3285db27053f8b237a758992fb55d6ddfbc264db399ff4f7a7db432900ca3a029daa28a75e0436231872091b1 +"regexp.prototype.flags@npm:^1.5.2": + version: 1.5.2 + resolution: "regexp.prototype.flags@npm:1.5.2" + dependencies: + call-bind: ^1.0.6 + define-properties: ^1.2.1 + es-errors: ^1.3.0 + set-function-name: ^2.0.1 + checksum: d7f333667d5c564e2d7a97c56c3075d64c722c9bb51b2b4df6822b2e8096d623a5e63088fb4c83df919b6951ef8113841de8b47de7224872fa6838bc5d8a7d64 languageName: node linkType: hard @@ -16462,35 +17215,28 @@ __metadata: languageName: node linkType: hard -"regexpu-core@npm:^4.7.1": - version: 4.7.1 - resolution: "regexpu-core@npm:4.7.1" +"regexpu-core@npm:^5.3.1": + version: 5.3.2 + resolution: "regexpu-core@npm:5.3.2" dependencies: - regenerate: ^1.4.0 - regenerate-unicode-properties: ^8.2.0 - regjsgen: ^0.5.1 - regjsparser: ^0.6.4 - unicode-match-property-ecmascript: ^1.0.4 - unicode-match-property-value-ecmascript: ^1.2.0 - checksum: 368b4aab72132ba3c8bd114822572c920d390ae99d3d219e0c7f872c6a0a3b1fbe30c88188ff90ec6f8e681667fa8e51d84a78bb05c460996a0df6a060b7ae80 - languageName: node - linkType: hard - -"regjsgen@npm:^0.5.1": - version: 0.5.2 - resolution: "regjsgen@npm:0.5.2" - checksum: 87c83d8488affae2493a823904de1a29a1867a07433c5e1142ad749b5606c5589b305fe35bfcc0972cf5a3b0d66b1f7999009e541be39a5d42c6041c59e2fb52 + "@babel/regjsgen": ^0.8.0 + regenerate: ^1.4.2 + regenerate-unicode-properties: ^10.1.0 + regjsparser: ^0.9.1 + unicode-match-property-ecmascript: ^2.0.0 + unicode-match-property-value-ecmascript: ^2.1.0 + checksum: 95bb97088419f5396e07769b7de96f995f58137ad75fac5811fb5fe53737766dfff35d66a0ee66babb1eb55386ef981feaef392f9df6d671f3c124812ba24da2 languageName: node linkType: hard -"regjsparser@npm:^0.6.4": - version: 0.6.9 - resolution: "regjsparser@npm:0.6.9" +"regjsparser@npm:^0.9.1": + version: 0.9.1 + resolution: "regjsparser@npm:0.9.1" dependencies: jsesc: ~0.5.0 bin: regjsparser: bin/parser - checksum: 1c439ec46a0be7834ec82fbb109396e088b6b73f0e9562cd67c37e3bdf85cc7cffe0192b3324da4491c7f709ce2b06fb2d59e12f0f9836b2e0cf26d5e54263aa + checksum: 5e1b76afe8f1d03c3beaf9e0d935dd467589c3625f6d65fb8ffa14f224d783a0fed4bf49c2c1b8211043ef92b6117313419edf055a098ed8342e340586741afc languageName: node linkType: hard @@ -16535,15 +17281,6 @@ __metadata: languageName: node linkType: hard -"repeating@npm:^2.0.0": - version: 2.0.1 - resolution: "repeating@npm:2.0.1" - dependencies: - is-finite: ^1.0.0 - checksum: d2db0b69c5cb0c14dd750036e0abcd6b3c3f7b2da3ee179786b755cf737ca15fa0fff417ca72de33d6966056f4695440e680a352401fc02c95ade59899afbdd0 - languageName: node - linkType: hard - "request-progress@npm:^3.0.0": version: 3.0.0 resolution: "request-progress@npm:3.0.0" @@ -16564,7 +17301,7 @@ __metadata: languageName: node linkType: hard -"request-promise-native@npm:^1.0.5, request-promise-native@npm:^1.0.8": +"request-promise-native@npm:^1.0.8": version: 1.0.9 resolution: "request-promise-native@npm:1.0.9" dependencies: @@ -16577,7 +17314,7 @@ __metadata: languageName: node linkType: hard -"request@npm:^2.87.0, request@npm:^2.88.0, request@npm:^2.88.2": +"request@npm:^2.88.2": version: 2.88.2 resolution: "request@npm:2.88.2" dependencies: @@ -16612,10 +17349,10 @@ __metadata: languageName: node linkType: hard -"require-main-filename@npm:^1.0.1": - version: 1.0.1 - resolution: "require-main-filename@npm:1.0.1" - checksum: 1fef30754da961f4e13c450c3eb60c7ae898a529c6ad6fa708a70bd2eed01564ceb299187b2899f5562804d797a059f39a5789884d0ac7b7ae1defc68fba4abf +"require-from-string@npm:^2.0.2": + version: 2.0.2 + resolution: "require-from-string@npm:2.0.2" + checksum: a03ef6895445f33a4015300c426699bc66b2b044ba7b670aa238610381b56d3f07c686251740d575e22f4c87531ba662d06937508f0f3c0f1ddc04db3130560b languageName: node linkType: hard @@ -16649,6 +17386,15 @@ __metadata: languageName: node linkType: hard +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: ^5.0.0 + checksum: 546e0816012d65778e580ad62b29e975a642989108d9a3c5beabfb2304192fa3c9f9146fbdfe213563c6ff51975ae41bac1d3c6e047dd9572c94863a057b4d81 + languageName: node + linkType: hard + "resolve-from@npm:^3.0.0": version: 3.0.0 resolution: "resolve-from@npm:3.0.0" @@ -16663,6 +17409,13 @@ __metadata: languageName: node linkType: hard +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + "resolve-pathname@npm:^3.0.0": version: 3.0.0 resolution: "resolve-pathname@npm:3.0.0" @@ -16670,21 +17423,21 @@ __metadata: languageName: node linkType: hard -"resolve-url-loader@npm:3.1.2": - version: 3.1.2 - resolution: "resolve-url-loader@npm:3.1.2" +"resolve-url-loader@npm:^3.1.2": + version: 3.1.5 + resolution: "resolve-url-loader@npm:3.1.5" dependencies: adjust-sourcemap-loader: 3.0.0 camelcase: 5.3.1 compose-function: 3.0.3 convert-source-map: 1.7.0 es6-iterator: 2.0.3 - loader-utils: 1.2.3 - postcss: 7.0.21 + loader-utils: ^1.2.3 + postcss: 7.0.36 rework: 1.0.1 rework-visit: 1.0.0 source-map: 0.6.1 - checksum: 02e559af8d10a8fda8d2cb1c61290b932787309309839288820438b4f25339a8c8cbd52598af89c1c1d277133d74914407e7a760e49acd966425a038798a6e70 + checksum: eb52911eff20723f07409cc12138d254fa0dd4a4f3b1ba11ee1b29912afb03f1272aaddb523658be1e3a946e0d1bf6f603d0e107753ab83d48ad2116cf04b7f6 languageName: node linkType: hard @@ -16695,23 +17448,17 @@ __metadata: languageName: node linkType: hard -"resolve@npm:1.1.7": - version: 1.1.7 - resolution: "resolve@npm:1.1.7" - checksum: afd20873fbde7641c9125efe3f940c2a99f6b1f90f1b7b743e744bdaac1cb105b2e4e0317bcc052ed7e31d57afa86b394a4dc9a1b33a297977be134fdf0250ab - languageName: node - linkType: hard - -"resolve@npm:1.15.0": - version: 1.15.0 - resolution: "resolve@npm:1.15.0" +"resolve@npm:1.18.1": + version: 1.18.1 + resolution: "resolve@npm:1.18.1" dependencies: + is-core-module: ^2.0.0 path-parse: ^1.0.6 - checksum: 6d5a48c4ddaad067d7d0d0557c58d0db342d878abccd4843af81ffd439b865157e8bf38029d05fdc02137da5bc7528d5120e3c270b38db2cb26973ffa9e2bebc + checksum: bab3686fa87576ac7e7f68481e25494f99b8413f3bc5048c5284eabe021f98917a50c625f8a1920a87ffc347b076c12a4a685d46d5fc98f337cf2dd3792014f4 languageName: node linkType: hard -"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.13.1, resolve@npm:^1.14.2, resolve@npm:^1.15.1, resolve@npm:^1.3.2, resolve@npm:^1.8.1": +"resolve@npm:^1.10.0, resolve@npm:^1.12.0, resolve@npm:^1.14.2, resolve@npm:^1.3.2": version: 1.20.0 resolution: "resolve@npm:1.20.0" dependencies: @@ -16721,23 +17468,43 @@ __metadata: languageName: node linkType: hard -"resolve@patch:resolve@1.1.7#~builtin": - version: 1.1.7 - resolution: "resolve@patch:resolve@npm%3A1.1.7#~builtin::version=1.1.7&hash=07638b" - checksum: e9dbca78600ae56835c43a09f1276876c883e4b4bbd43e2683fa140671519d2bdebeb1c1576ca87c8c508ae2987b3ec481645ac5d3054b0f23254cfc1ce49942 +"resolve@npm:^1.17.0, resolve@npm:^1.18.1, resolve@npm:^1.19.0, resolve@npm:^1.22.4": + version: 1.22.8 + resolution: "resolve@npm:1.22.8" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: f8a26958aa572c9b064562750b52131a37c29d072478ea32e129063e2da7f83e31f7f11e7087a18225a8561cfe8d2f0df9dbea7c9d331a897571c0a2527dbb4c languageName: node linkType: hard -"resolve@patch:resolve@1.15.0#~builtin": - version: 1.15.0 - resolution: "resolve@patch:resolve@npm%3A1.15.0#~builtin::version=1.15.0&hash=07638b" +"resolve@npm:^2.0.0-next.5": + version: 2.0.0-next.5 + resolution: "resolve@npm:2.0.0-next.5" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: a73ac69a1c4bd34c56b213d91f5b17ce390688fdb4a1a96ed3025cc7e08e7bfb90b3a06fcce461780cb0b589c958afcb0080ab802c71c01a7ecc8c64feafc89f + languageName: node + linkType: hard + +"resolve@patch:resolve@1.18.1#~builtin": + version: 1.18.1 + resolution: "resolve@patch:resolve@npm%3A1.18.1#~builtin::version=1.18.1&hash=07638b" dependencies: + is-core-module: ^2.0.0 path-parse: ^1.0.6 - checksum: fd308e2054e85f829a29e2a5f4634942272b9bfc2771f95fbd1c2068f47a7f4f0f5d4ccb11cb4522f9a8490edd036299f7a85e76327ed8b91bd1a41d314e2bf0 + checksum: 7439c8f3d8fa00c9dc800ef3c8ed0bd8e8772823e6e4948b1a77487759e0fb905381808caae96398d135619af90654d8e74cac778e5b8c9d7138f2dd52bb2bba languageName: node linkType: hard -"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.13.1#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.15.1#~builtin, resolve@patch:resolve@^1.3.2#~builtin, resolve@patch:resolve@^1.8.1#~builtin": +"resolve@patch:resolve@^1.10.0#~builtin, resolve@patch:resolve@^1.12.0#~builtin, resolve@patch:resolve@^1.14.2#~builtin, resolve@patch:resolve@^1.3.2#~builtin": version: 1.20.0 resolution: "resolve@patch:resolve@npm%3A1.20.0#~builtin::version=1.20.0&hash=07638b" dependencies: @@ -16747,6 +17514,32 @@ __metadata: languageName: node linkType: hard +"resolve@patch:resolve@^1.17.0#~builtin, resolve@patch:resolve@^1.18.1#~builtin, resolve@patch:resolve@^1.19.0#~builtin, resolve@patch:resolve@^1.22.4#~builtin": + version: 1.22.8 + resolution: "resolve@patch:resolve@npm%3A1.22.8#~builtin::version=1.22.8&hash=07638b" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 5479b7d431cacd5185f8db64bfcb7286ae5e31eb299f4c4f404ad8aa6098b77599563ac4257cb2c37a42f59dfc06a1bec2bcf283bb448f319e37f0feb9a09847 + languageName: node + linkType: hard + +"resolve@patch:resolve@^2.0.0-next.5#~builtin": + version: 2.0.0-next.5 + resolution: "resolve@patch:resolve@npm%3A2.0.0-next.5#~builtin::version=2.0.0-next.5&hash=07638b" + dependencies: + is-core-module: ^2.13.0 + path-parse: ^1.0.7 + supports-preserve-symlinks-flag: ^1.0.0 + bin: + resolve: bin/resolve + checksum: 064d09c1808d0c51b3d90b5d27e198e6d0c5dad0eb57065fd40803d6a20553e5398b07f76739d69cbabc12547058bec6b32106ea66622375fb0d7e8fca6a846c + languageName: node + linkType: hard + "restore-cursor@npm:^3.1.0": version: 3.1.0 resolution: "restore-cursor@npm:3.1.0" @@ -16816,7 +17609,7 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:2, rimraf@npm:^2.5.4, rimraf@npm:^2.6.3, rimraf@npm:^2.7.1": +"rimraf@npm:2, rimraf@npm:^2.5.4, rimraf@npm:^2.6.3": version: 2.7.1 resolution: "rimraf@npm:2.7.1" dependencies: @@ -16827,35 +17620,74 @@ __metadata: languageName: node linkType: hard -"rimraf@npm:2.6.3": - version: 2.6.3 - resolution: "rimraf@npm:2.6.3" +"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: ^7.1.3 + bin: + rimraf: bin.js + checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 + languageName: node + linkType: hard + +"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": + version: 2.0.2 + resolution: "ripemd160@npm:2.0.2" + dependencies: + hash-base: ^3.0.0 + inherits: ^2.0.1 + checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + languageName: node + linkType: hard + +"rollup-plugin-babel@npm:^4.3.3": + version: 4.4.0 + resolution: "rollup-plugin-babel@npm:4.4.0" + dependencies: + "@babel/helper-module-imports": ^7.0.0 + rollup-pluginutils: ^2.8.1 + peerDependencies: + "@babel/core": 7 || ^7.0.0-rc.2 + rollup: ">=0.60.0 <3" + checksum: 5b8ed7c0a4192d7c74689074c910c1670eb07dfc875b1f4af5694a94c46bcb168ba85e2c9753030131efd6261ece7c252b9695953d0ea96d944977c6e79930d3 + languageName: node + linkType: hard + +"rollup-plugin-terser@npm:^5.3.1": + version: 5.3.1 + resolution: "rollup-plugin-terser@npm:5.3.1" dependencies: - glob: ^7.1.3 - bin: - rimraf: ./bin.js - checksum: 3ea587b981a19016297edb96d1ffe48af7e6af69660e3b371dbfc73722a73a0b0e9be5c88089fbeeb866c389c1098e07f64929c7414290504b855f54f901ab10 + "@babel/code-frame": ^7.5.5 + jest-worker: ^24.9.0 + rollup-pluginutils: ^2.8.2 + serialize-javascript: ^4.0.0 + terser: ^4.6.2 + peerDependencies: + rollup: ">=0.66.0 <3" + checksum: 50f9e8fa6737fa5e8aeca6a52b59ea3bc66faebe743bdfe9ce0484298cd1978082026721b182d79bcc88240429842dc58feae88d6c238b47cafc1684e0320a73 languageName: node linkType: hard -"rimraf@npm:^3.0.0, rimraf@npm:^3.0.2": - version: 3.0.2 - resolution: "rimraf@npm:3.0.2" +"rollup-pluginutils@npm:^2.8.1, rollup-pluginutils@npm:^2.8.2": + version: 2.8.2 + resolution: "rollup-pluginutils@npm:2.8.2" dependencies: - glob: ^7.1.3 - bin: - rimraf: bin.js - checksum: 87f4164e396f0171b0a3386cc1877a817f572148ee13a7e113b238e48e8a9f2f31d009a92ec38a591ff1567d9662c6b67fd8818a2dbbaed74bc26a87a2a4a9a0 + estree-walker: ^0.6.1 + checksum: 339fdf866d8f4ff6e408fa274c0525412f7edb01dc46b5ccda51f575b7e0d20ad72965773376fb5db95a77a7fcfcab97bf841ec08dbadf5d6b08af02b7a2cf5e languageName: node linkType: hard -"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1": - version: 2.0.2 - resolution: "ripemd160@npm:2.0.2" +"rollup@npm:^1.31.1": + version: 1.32.1 + resolution: "rollup@npm:1.32.1" dependencies: - hash-base: ^3.0.0 - inherits: ^2.0.1 - checksum: 006accc40578ee2beae382757c4ce2908a826b27e2b079efdcd2959ee544ddf210b7b5d7d5e80467807604244e7388427330f5c6d4cd61e6edaddc5773ccc393 + "@types/estree": "*" + "@types/node": "*" + acorn: ^7.1.0 + bin: + rollup: dist/bin/rollup + checksum: 3a02731c20c71321fae647c9c9cab0febee0580c6af029fdcd5dd6f424b8c85119d92c8554c6837327fd323c2458e92d955bbebc90ca6bed87cc626695e7c31f languageName: node linkType: hard @@ -16876,13 +17708,6 @@ __metadata: languageName: node linkType: hard -"run-async@npm:^2.2.0, run-async@npm:^2.4.0": - version: 2.4.1 - resolution: "run-async@npm:2.4.1" - checksum: a2c88aa15df176f091a2878eb840e68d0bdee319d8d97bbb89112223259cebecb94bc0defd735662b83c2f7a30bed8cddb7d1674eb48ae7322dc602b22d03797 - languageName: node - linkType: hard - "run-parallel@npm:^1.1.9": version: 1.2.0 resolution: "run-parallel@npm:1.2.0" @@ -16901,7 +17726,7 @@ __metadata: languageName: node linkType: hard -"rxjs@npm:^6.5.3, rxjs@npm:^6.5.5, rxjs@npm:^6.6.0": +"rxjs@npm:^6.5.5": version: 6.6.7 resolution: "rxjs@npm:6.6.7" dependencies: @@ -16919,6 +17744,18 @@ __metadata: languageName: node linkType: hard +"safe-array-concat@npm:^1.1.2": + version: 1.1.2 + resolution: "safe-array-concat@npm:1.1.2" + dependencies: + call-bind: ^1.0.7 + get-intrinsic: ^1.2.4 + has-symbols: ^1.0.3 + isarray: ^2.0.5 + checksum: a3b259694754ddfb73ae0663829e396977b99ff21cbe8607f35a469655656da8e271753497e59da8a7575baa94d2e684bea3e10ddd74ba046c0c9b4418ffa0c4 + languageName: node + linkType: hard + "safe-buffer@npm:5.1.2, safe-buffer@npm:~5.1.0, safe-buffer@npm:~5.1.1": version: 5.1.2 resolution: "safe-buffer@npm:5.1.2" @@ -16933,6 +17770,17 @@ __metadata: languageName: node linkType: hard +"safe-regex-test@npm:^1.0.3": + version: 1.0.3 + resolution: "safe-regex-test@npm:1.0.3" + dependencies: + call-bind: ^1.0.6 + es-errors: ^1.3.0 + is-regex: ^1.1.4 + checksum: 6c7d392ff1ae7a3ae85273450ed02d1d131f1d2c76e177d6b03eb88e6df8fa062639070e7d311802c1615f351f18dc58f9454501c58e28d5ffd9b8f502ba6489 + languageName: node + linkType: hard + "safe-regex@npm:^1.1.0": version: 1.1.0 resolution: "safe-regex@npm:1.1.0" @@ -16975,20 +17823,6 @@ __metadata: languageName: node linkType: hard -"sass-graph@npm:^2.2.4": - version: 2.2.6 - resolution: "sass-graph@npm:2.2.6" - dependencies: - glob: ^7.0.0 - lodash: ^4.0.0 - scss-tokenizer: ^0.2.3 - yargs: ^7.0.0 - bin: - sassgraph: bin/sassgraph - checksum: 1fb1719c659fdea00a9f55be9722c5902c3d1f1a0919d2e5ceb8a318064f2b214981d98b7d7fecaafc25f522302f919a948351e4ae1d1680b9c045d563550a93 - languageName: node - linkType: hard - "sass-graph@npm:^4.0.1": version: 4.0.1 resolution: "sass-graph@npm:4.0.1" @@ -17028,19 +17862,19 @@ __metadata: languageName: node linkType: hard -"sax@npm:^1.2.4, sax@npm:~1.2.4": +"sax@npm:~1.2.4": version: 1.2.4 resolution: "sax@npm:1.2.4" checksum: d3df7d32b897a2c2f28e941f732c71ba90e27c24f62ee918bd4d9a8cfb3553f2f81e5493c7f0be94a11c1911b643a9108f231dd6f60df3fa9586b5d2e3e9e1fe languageName: node linkType: hard -"saxes@npm:^3.1.9": - version: 3.1.11 - resolution: "saxes@npm:3.1.11" +"saxes@npm:^5.0.1": + version: 5.0.1 + resolution: "saxes@npm:5.0.1" dependencies: - xmlchars: ^2.1.1 - checksum: 3b69918c013fffae51c561f629a0f620c02dba70f762dab38f3cd92676dfe5edf1f0a523ca567882838f1a80e26e4671a8c2c689afa05c68f45a78261445aba0 + xmlchars: ^2.2.0 + checksum: 5636b55cf15f7cf0baa73f2797bf992bdcf75d1b39d82c0aa4608555c774368f6ac321cb641fd5f3d3ceb87805122cd47540da6a7b5960fe0dbdb8f8c263f000 languageName: node linkType: hard @@ -17065,7 +17899,7 @@ __metadata: languageName: node linkType: hard -"schema-utils@npm:^2.5.0, schema-utils@npm:^2.6.0, schema-utils@npm:^2.6.1, schema-utils@npm:^2.6.5, schema-utils@npm:^2.6.6": +"schema-utils@npm:^2.6.1, schema-utils@npm:^2.6.5, schema-utils@npm:^2.7.0, schema-utils@npm:^2.7.1": version: 2.7.1 resolution: "schema-utils@npm:2.7.1" dependencies: @@ -17076,13 +17910,14 @@ __metadata: languageName: node linkType: hard -"scss-tokenizer@npm:^0.2.3": - version: 0.2.3 - resolution: "scss-tokenizer@npm:0.2.3" +"schema-utils@npm:^3.0.0, schema-utils@npm:^3.1.1": + version: 3.3.0 + resolution: "schema-utils@npm:3.3.0" dependencies: - js-base64: ^2.1.8 - source-map: ^0.4.2 - checksum: ad78bba4466ff7aa6449931a57a980479223c3cad9eccf2180251c2f6fce5b3d982a51f924709e0a0bb2d328dedbb2fad0ccb2a5fdc175513a27cb4e8cf8cfd2 + "@types/json-schema": ^7.0.8 + ajv: ^6.12.5 + ajv-keywords: ^3.5.2 + checksum: ea56971926fac2487f0757da939a871388891bc87c6a82220d125d587b388f1704788f3706e7f63a7b70e49fc2db974c41343528caea60444afd5ce0fe4b85c0 languageName: node linkType: hard @@ -17112,7 +17947,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.5.1, semver@npm:^5.6.0, semver@npm:^5.7.0, semver@npm:^5.7.1": +"semver@npm:2 || 3 || 4 || 5, semver@npm:^5.3.0, semver@npm:^5.4.1, semver@npm:^5.5.0, semver@npm:^5.6.0, semver@npm:^5.7.0, semver@npm:^5.7.1": version: 5.7.2 resolution: "semver@npm:5.7.2" bin: @@ -17121,25 +17956,16 @@ __metadata: languageName: node linkType: hard -"semver@npm:6.3.0": - version: 6.3.0 - resolution: "semver@npm:6.3.0" - bin: - semver: ./bin/semver.js - checksum: 1b26ecf6db9e8292dd90df4e781d91875c0dcc1b1909e70f5d12959a23c7eebb8f01ea581c00783bbee72ceeaad9505797c381756326073850dc36ed284b21b9 - languageName: node - linkType: hard - -"semver@npm:7.0.0": - version: 7.0.0 - resolution: "semver@npm:7.0.0" +"semver@npm:7.3.2": + version: 7.3.2 + resolution: "semver@npm:7.3.2" bin: semver: bin/semver.js - checksum: 272c11bf8d083274ef79fe40a81c55c184dff84dd58e3c325299d0927ba48cece1f020793d138382b85f89bab5002a35a5ba59a3a68a7eebbb597eb733838778 + checksum: 692f4900dadb43919614b0df9af23fe05743051cda0d1735b5e4d76f93c9e43a266fae73cfc928f5d1489f022c5c0e65dfd2900fcf5b1839c4e9a239729afa7b languageName: node linkType: hard -"semver@npm:^6.0.0, semver@npm:^6.1.1, semver@npm:^6.1.2, semver@npm:^6.2.0, semver@npm:^6.3.0, semver@npm:^6.3.1": +"semver@npm:^6.0.0, semver@npm:^6.3.0, semver@npm:^6.3.1": version: 6.3.1 resolution: "semver@npm:6.3.1" bin: @@ -17148,25 +17974,25 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.3.4, semver@npm:^7.3.5": - version: 7.5.4 - resolution: "semver@npm:7.5.4" +"semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.5.3": + version: 7.6.0 + resolution: "semver@npm:7.6.0" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 + checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c languageName: node linkType: hard -"semver@npm:^7.5.3": - version: 7.6.0 - resolution: "semver@npm:7.6.0" +"semver@npm:^7.3.4, semver@npm:^7.3.5": + version: 7.5.4 + resolution: "semver@npm:7.5.4" dependencies: lru-cache: ^6.0.0 bin: semver: bin/semver.js - checksum: 7427f05b70786c696640edc29fdd4bc33b2acf3bbe1740b955029044f80575fc664e1a512e4113c3af21e767154a94b4aa214bf6cd6e42a1f6dba5914e0b208c + checksum: 12d8ad952fa353b0995bf180cdac205a4068b759a140e5d3c608317098b3575ac2f1e09182206bf2eb26120e1c0ed8fb92c48c592f6099680de56bb071423ca3 languageName: node linkType: hard @@ -17200,6 +18026,15 @@ __metadata: languageName: node linkType: hard +"serialize-javascript@npm:^5.0.1": + version: 5.0.1 + resolution: "serialize-javascript@npm:5.0.1" + dependencies: + randombytes: ^2.1.0 + checksum: bb45a427690c3d2711e28499de0fbf25036af1e23c63c6a9237ed0aa572fd0941fcdefe50a2dccf26d9df8c8b86ae38659e19d8ba7afd3fbc1f1c7539a2a48d2 + languageName: node + linkType: hard + "serve-index@npm:^1.9.1": version: 1.9.1 resolution: "serve-index@npm:1.9.1" @@ -17234,6 +18069,32 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.2.1": + version: 1.2.2 + resolution: "set-function-length@npm:1.2.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + function-bind: ^1.1.2 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-property-descriptors: ^1.0.2 + checksum: a8248bdacdf84cb0fab4637774d9fb3c7a8e6089866d04c817583ff48e14149c87044ce683d7f50759a8c50fb87c7a7e173535b06169c87ef76f5fb276dfff72 + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.1, set-function-name@npm:^2.0.2": + version: 2.0.2 + resolution: "set-function-name@npm:2.0.2" + dependencies: + define-data-property: ^1.1.4 + es-errors: ^1.3.0 + functions-have-names: ^1.2.3 + has-property-descriptors: ^1.0.2 + checksum: d6229a71527fd0404399fc6227e0ff0652800362510822a291925c9d7b48a1ca1a468b11b281471c34cd5a2da0db4f5d7ff315a61d26655e77f6e971e6d0c80f + languageName: node + linkType: hard + "set-value@npm:2.0.1, set-value@npm:^2.0.0, set-value@npm:^2.0.1": version: 2.0.1 resolution: "set-value@npm:2.0.1" @@ -17279,18 +18140,6 @@ __metadata: languageName: node linkType: hard -"shallow-clone@npm:^0.1.2": - version: 0.1.2 - resolution: "shallow-clone@npm:0.1.2" - dependencies: - is-extendable: ^0.1.1 - kind-of: ^2.0.1 - lazy-cache: ^0.2.3 - mixin-object: ^2.0.1 - checksum: cc4c85c6e42186fec33a81a85622c48dbcfdf280f3a7bd0800b4de57df8e365a8760aa2e31dd79df365b317dddb2fd0bbd92be0aab14dbd2de6a65992eab2177 - languageName: node - linkType: hard - "shallow-clone@npm:^3.0.0": version: 3.0.1 resolution: "shallow-clone@npm:3.0.1" @@ -17371,6 +18220,18 @@ __metadata: languageName: node linkType: hard +"side-channel@npm:^1.0.6": + version: 1.0.6 + resolution: "side-channel@npm:1.0.6" + dependencies: + call-bind: ^1.0.7 + es-errors: ^1.3.0 + get-intrinsic: ^1.2.4 + object-inspect: ^1.13.1 + checksum: bfc1afc1827d712271453e91b7cd3878ac0efd767495fd4e594c4c2afaa7963b7b510e249572bfd54b0527e66e4a12b61b80c061389e129755f34c493aad9b97 + languageName: node + linkType: hard + "signal-exit@npm:^3.0.0, signal-exit@npm:^3.0.2": version: 3.0.3 resolution: "signal-exit@npm:3.0.3" @@ -17416,20 +18277,6 @@ __metadata: languageName: node linkType: hard -"slash@npm:^1.0.0": - version: 1.0.0 - resolution: "slash@npm:1.0.0" - checksum: 4b6e21b1fba6184a7e2efb1dd173f692d8a845584c1bbf9dc818ff86f5a52fc91b413008223d17cc684604ee8bb9263a420b1182027ad9762e35388434918860 - languageName: node - linkType: hard - -"slash@npm:^2.0.0": - version: 2.0.0 - resolution: "slash@npm:2.0.0" - checksum: 512d4350735375bd11647233cb0e2f93beca6f53441015eea241fe784d8068281c3987fbaa93e7ef1c38df68d9c60013045c92837423c69115297d6169aa85e6 - languageName: node - linkType: hard - "slash@npm:^3.0.0": version: 3.0.0 resolution: "slash@npm:3.0.0" @@ -17437,17 +18284,6 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^2.1.0": - version: 2.1.0 - resolution: "slice-ansi@npm:2.1.0" - dependencies: - ansi-styles: ^3.2.0 - astral-regex: ^1.0.0 - is-fullwidth-code-point: ^2.0.0 - checksum: 4e82995aa59cef7eb03ef232d73c2239a15efa0ace87a01f3012ebb942e963fbb05d448ce7391efcd52ab9c32724164aba2086f5143e0445c969221dde3b6b1e - languageName: node - linkType: hard - "slice-ansi@npm:^3.0.0": version: 3.0.0 resolution: "slice-ansi@npm:3.0.0" @@ -17614,6 +18450,13 @@ __metadata: languageName: node linkType: hard +"source-map-js@npm:^1.2.0": + version: 1.2.0 + resolution: "source-map-js@npm:1.2.0" + checksum: 791a43306d9223792e84293b00458bf102a8946e7188f3db0e4e22d8d530b5f80a4ce468eb5ec0bf585443ad55ebbd630bf379c98db0b1f317fd902500217f97 + languageName: node + linkType: hard + "source-map-resolve@npm:^0.5.0, source-map-resolve@npm:^0.5.2": version: 0.5.3 resolution: "source-map-resolve@npm:0.5.3" @@ -17637,6 +18480,16 @@ __metadata: languageName: node linkType: hard +"source-map-support@npm:~0.5.20": + version: 0.5.21 + resolution: "source-map-support@npm:0.5.21" + dependencies: + buffer-from: ^1.0.0 + source-map: ^0.6.0 + checksum: 43e98d700d79af1d36f859bdb7318e601dfc918c7ba2e98456118ebc4c4872b327773e5a1df09b0524e9e5063bb18f0934538eace60cca2710d1fa687645d137 + languageName: node + linkType: hard + "source-map-url@npm:^0.4.0": version: 0.4.1 resolution: "source-map-url@npm:0.4.1" @@ -17651,15 +18504,6 @@ __metadata: languageName: node linkType: hard -"source-map@npm:^0.4.2": - version: 0.4.4 - resolution: "source-map@npm:0.4.4" - dependencies: - amdefine: ">=0.0.4" - checksum: b31992fcb4a2a6c335617f187bd36f392896dfcc111830ebdb8b716923cf6554b665833b975fc998bdf3a63881b2c8b4c5c34fda0280357b8c18fe6aa5d148ea - languageName: node - linkType: hard - "source-map@npm:^0.5.0, source-map@npm:^0.5.6": version: 0.5.7 resolution: "source-map@npm:0.5.7" @@ -17674,6 +18518,13 @@ __metadata: languageName: node linkType: hard +"sourcemap-codec@npm:^1.4.8": + version: 1.4.8 + resolution: "sourcemap-codec@npm:1.4.8" + checksum: b57981c05611afef31605732b598ccf65124a9fcb03b833532659ac4d29ac0f7bfacbc0d6c5a28a03e84c7510e7e556d758d0bb57786e214660016fb94279316 + languageName: node + linkType: hard + "spdx-correct@npm:^3.0.0": version: 3.1.1 resolution: "spdx-correct@npm:3.1.1" @@ -17809,16 +18660,6 @@ __metadata: languageName: node linkType: hard -"ssri@npm:^7.0.0": - version: 7.1.1 - resolution: "ssri@npm:7.1.1" - dependencies: - figgy-pudding: ^3.5.1 - minipass: ^3.1.1 - checksum: 8bdb3c198a3cebda54344b3cd9599338c18a4b29f1c857c0ab98cb39ff11a36b4cb6ea5a388c22bd71ac1ae6d8129103336173f77487d94d772eeb9aa0c8545f - languageName: node - linkType: hard - "ssri@npm:^8.0.0, ssri@npm:^8.0.1": version: 8.0.1 resolution: "ssri@npm:8.0.1" @@ -17844,12 +18685,28 @@ __metadata: languageName: node linkType: hard -"stack-utils@npm:^1.0.1": - version: 1.0.5 - resolution: "stack-utils@npm:1.0.5" +"stack-utils@npm:^2.0.2": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" dependencies: escape-string-regexp: ^2.0.0 - checksum: f82baf8d89536252a55c76866d5be3d04c96b09693a8d2ab3794b9fdec3674e05bd3f3d19345093e2cbba116a1f8f413858e0537bc3c81c605249261c3d26182 + checksum: 052bf4d25bbf5f78e06c1d5e67de2e088b06871fa04107ca8d3f0e9d9263326e2942c8bedee3545795fc77d787d443a538345eef74db2f8e35db3558c6f91ff7 + languageName: node + linkType: hard + +"stackframe@npm:^1.3.4": + version: 1.3.4 + resolution: "stackframe@npm:1.3.4" + checksum: bae1596873595c4610993fa84f86a3387d67586401c1816ea048c0196800c0646c4d2da98c2ee80557fd9eff05877efe33b91ba6cd052658ed96ddc85d19067d + languageName: node + linkType: hard + +"static-eval@npm:2.0.2": + version: 2.0.2 + resolution: "static-eval@npm:2.0.2" + dependencies: + escodegen: ^1.8.1 + checksum: 335a923c5ccb29add404ac23d0a55c0da6cee3071f6f67a7053aeac0dedc6dbfc53ac9269e9c25f403f5b7603a291ef47d7114f99bde241184f7aa3f9286dc32 languageName: node linkType: hard @@ -17947,34 +18804,20 @@ __metadata: languageName: node linkType: hard -"string-length@npm:^2.0.0": - version: 2.0.0 - resolution: "string-length@npm:2.0.0" - dependencies: - astral-regex: ^1.0.0 - strip-ansi: ^4.0.0 - checksum: 3a339b63fd39d6a1077dfbbe3279545e1b67fa4b0a558906158cf0121632b280f34c8768ec7270fb25db732d6323eceb9c7254f6026509694b6a7533ca8cb89e - languageName: node - linkType: hard - -"string-length@npm:^3.1.0": - version: 3.1.0 - resolution: "string-length@npm:3.1.0" +"string-length@npm:^4.0.1": + version: 4.0.2 + resolution: "string-length@npm:4.0.2" dependencies: - astral-regex: ^1.0.0 - strip-ansi: ^5.2.0 - checksum: b09ccacc2f96ba3ade9f2b3163901e05f668a2b14bc353853165c1f3b19185421ac004e9957b62827083d163e049c41a1b15170e252eaf44fdd686553c372714 + char-regex: ^1.0.2 + strip-ansi: ^6.0.0 + checksum: ce85533ef5113fcb7e522bcf9e62cb33871aa99b3729cec5595f4447f660b0cefd542ca6df4150c97a677d58b0cb727a3fe09ac1de94071d05526c73579bf505 languageName: node linkType: hard -"string-width@npm:^1.0.1, string-width@npm:^1.0.2": - version: 1.0.2 - resolution: "string-width@npm:1.0.2" - dependencies: - code-point-at: ^1.0.0 - is-fullwidth-code-point: ^1.0.0 - strip-ansi: ^3.0.0 - checksum: 5c79439e95bc3bd7233a332c5f5926ab2ee90b23816ed4faa380ce3b2576d7800b0a5bb15ae88ed28737acc7ea06a518c2eef39142dd727adad0e45c776cd37e +"string-natural-compare@npm:^3.0.1": + version: 3.0.1 + resolution: "string-natural-compare@npm:3.0.1" + checksum: 65910d9995074086e769a68728395effbba9b7186be5b4c16a7fad4f4ef50cae95ca16e3e9086e019cbb636ae8daac9c7b8fe91b5f21865c5c0f26e3c0725406 languageName: node linkType: hard @@ -18011,19 +18854,23 @@ __metadata: languageName: node linkType: hard -"string.prototype.matchall@npm:^4.0.2": - version: 4.0.5 - resolution: "string.prototype.matchall@npm:4.0.5" +"string.prototype.matchall@npm:^4.0.10": + version: 4.0.11 + resolution: "string.prototype.matchall@npm:4.0.11" dependencies: - call-bind: ^1.0.2 - define-properties: ^1.1.3 - es-abstract: ^1.18.2 - get-intrinsic: ^1.1.1 - has-symbols: ^1.0.2 - internal-slot: ^1.0.3 - regexp.prototype.flags: ^1.3.1 - side-channel: ^1.0.4 - checksum: 0a9d64661ecf089e7712aed18a4b0d7e4093ae1dfc6d8134747a98271564065a2a667a3408fced4a77137528b3b2c0efe9d37868acae000ee13d0857a3d0f430 + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.2 + es-errors: ^1.3.0 + es-object-atoms: ^1.0.0 + get-intrinsic: ^1.2.4 + gopd: ^1.0.1 + has-symbols: ^1.0.3 + internal-slot: ^1.0.7 + regexp.prototype.flags: ^1.5.2 + set-function-name: ^2.0.2 + side-channel: ^1.0.6 + checksum: 6ac6566ed065c0c8489c91156078ca077db8ff64d683fda97ae652d00c52dfa5f39aaab0a710d8243031a857fd2c7c511e38b45524796764d25472d10d7075ae languageName: node linkType: hard @@ -18038,6 +18885,18 @@ __metadata: languageName: node linkType: hard +"string.prototype.trim@npm:^1.2.9": + version: 1.2.9 + resolution: "string.prototype.trim@npm:1.2.9" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-abstract: ^1.23.0 + es-object-atoms: ^1.0.0 + checksum: ea2df6ec1e914c9d4e2dc856fa08228e8b1be59b59e50b17578c94a66a176888f417264bb763d4aac638ad3b3dad56e7a03d9317086a178078d131aa293ba193 + languageName: node + linkType: hard + "string.prototype.trimend@npm:^1.0.4": version: 1.0.4 resolution: "string.prototype.trimend@npm:1.0.4" @@ -18048,6 +18907,17 @@ __metadata: languageName: node linkType: hard +"string.prototype.trimend@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimend@npm:1.0.8" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: cc3bd2de08d8968a28787deba9a3cb3f17ca5f9f770c91e7e8fa3e7d47f079bad70fadce16f05dda9f261788be2c6e84a942f618c3bed31e42abc5c1084f8dfd + languageName: node + linkType: hard + "string.prototype.trimstart@npm:^1.0.4": version: 1.0.4 resolution: "string.prototype.trimstart@npm:1.0.4" @@ -18058,6 +18928,17 @@ __metadata: languageName: node linkType: hard +"string.prototype.trimstart@npm:^1.0.8": + version: 1.0.8 + resolution: "string.prototype.trimstart@npm:1.0.8" + dependencies: + call-bind: ^1.0.7 + define-properties: ^1.2.1 + es-object-atoms: ^1.0.0 + checksum: df1007a7f580a49d692375d996521dc14fd103acda7f3034b3c558a60b82beeed3a64fa91e494e164581793a8ab0ae2f59578a49896a7af6583c1f20472bce96 + languageName: node + linkType: hard + "string_decoder@npm:^1.0.0, string_decoder@npm:^1.1.1": version: 1.3.0 resolution: "string_decoder@npm:1.3.0" @@ -18096,7 +18977,7 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1": +"strip-ansi@npm:^3.0.1": version: 3.0.1 resolution: "strip-ansi@npm:3.0.1" dependencies: @@ -18105,15 +18986,6 @@ __metadata: languageName: node linkType: hard -"strip-ansi@npm:^4.0.0": - version: 4.0.0 - resolution: "strip-ansi@npm:4.0.0" - dependencies: - ansi-regex: ^3.0.0 - checksum: d9186e6c0cf78f25274f6750ee5e4a5725fb91b70fdd79aa5fe648eab092a0ec5b9621b22d69d4534a56319f75d8944efbd84e3afa8d4ad1b9a9491f12c84eca - languageName: node - linkType: hard - "strip-ansi@npm:^5.0.0, strip-ansi@npm:^5.1.0, strip-ansi@npm:^5.2.0": version: 5.2.0 resolution: "strip-ansi@npm:5.2.0" @@ -18132,15 +19004,6 @@ __metadata: languageName: node linkType: hard -"strip-bom@npm:^2.0.0": - version: 2.0.0 - resolution: "strip-bom@npm:2.0.0" - dependencies: - is-utf8: ^0.2.0 - checksum: 08efb746bc67b10814cd03d79eb31bac633393a782e3f35efbc1b61b5165d3806d03332a97f362822cf0d4dd14ba2e12707fcff44fe1c870c48a063a0c9e4944 - languageName: node - linkType: hard - "strip-bom@npm:^3.0.0": version: 3.0.0 resolution: "strip-bom@npm:3.0.0" @@ -18148,6 +19011,13 @@ __metadata: languageName: node linkType: hard +"strip-bom@npm:^4.0.0": + version: 4.0.0 + resolution: "strip-bom@npm:4.0.0" + checksum: 9dbcfbaf503c57c06af15fe2c8176fb1bf3af5ff65003851a102749f875a6dbe0ab3b30115eccf6e805e9d756830d3e40ec508b62b3f1ddf3761a20ebe29d3f3 + languageName: node + linkType: hard + "strip-comments@npm:^1.0.2": version: 1.0.2 resolution: "strip-comments@npm:1.0.2" @@ -18172,17 +19042,6 @@ __metadata: languageName: node linkType: hard -"strip-indent@npm:^1.0.1": - version: 1.0.1 - resolution: "strip-indent@npm:1.0.1" - dependencies: - get-stdin: ^4.0.1 - bin: - strip-indent: cli.js - checksum: 81ad9a0b8a558bdbd05b66c6c437b9ab364aa2b5479ed89969ca7908e680e21b043d40229558c434b22b3d640622e39b66288e0456d601981ac9289de9700fbd - languageName: node - linkType: hard - "strip-indent@npm:^3.0.0": version: 3.0.0 resolution: "strip-indent@npm:3.0.0" @@ -18192,20 +19051,22 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:^3.0.1": +"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 languageName: node linkType: hard -"style-loader@npm:0.23.1": - version: 0.23.1 - resolution: "style-loader@npm:0.23.1" +"style-loader@npm:1.3.0": + version: 1.3.0 + resolution: "style-loader@npm:1.3.0" dependencies: - loader-utils: ^1.1.0 - schema-utils: ^1.0.0 - checksum: 0a513a2d881e88bbfd574750df3dc61f57424684458d94cb6ae41e635d03abfa8974bb591eab9051650082c5f5502994dc17c7ca9fb0fc9e8d31f651f6737479 + loader-utils: ^2.0.0 + schema-utils: ^2.7.0 + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + checksum: 1be9e8705307f5b8eb89e80f3703fa27296dccec349d790eace7aabe212f08c7c8f3ea6b6cb97bc53e82fbebfb9aa0689259671a8315f4655e24a850781e062a languageName: node linkType: hard @@ -18247,13 +19108,6 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^2.0.0": - version: 2.0.0 - resolution: "supports-color@npm:2.0.0" - checksum: 602538c5812b9006404370b5a4b885d3e2a1f6567d314f8b4a41974ffe7d08e525bf92ae0f9c7030e3b4c78e4e34ace55d6a67a74f1571bc205959f5972f88f0 - languageName: node - linkType: hard - "supports-color@npm:^5.3.0, supports-color@npm:^5.5.0": version: 5.5.0 resolution: "supports-color@npm:5.5.0" @@ -18281,7 +19135,7 @@ __metadata: languageName: node linkType: hard -"supports-color@npm:^8.1.1": +"supports-color@npm:^8.0.0, supports-color@npm:^8.1.1": version: 8.1.1 resolution: "supports-color@npm:8.1.1" dependencies: @@ -18290,7 +19144,24 @@ __metadata: languageName: node linkType: hard -"svg-parser@npm:^2.0.0": +"supports-hyperlinks@npm:^2.0.0": + version: 2.3.0 + resolution: "supports-hyperlinks@npm:2.3.0" + dependencies: + has-flag: ^4.0.0 + supports-color: ^7.0.0 + checksum: 9ee0de3c8ce919d453511b2b1588a8205bd429d98af94a01df87411391010fe22ca463f268c84b2ce2abad019dfff8452aa02806eeb5c905a8d7ad5c4f4c52b8 + languageName: node + linkType: hard + +"supports-preserve-symlinks-flag@npm:^1.0.0": + version: 1.0.0 + resolution: "supports-preserve-symlinks-flag@npm:1.0.0" + checksum: 53b1e247e68e05db7b3808b99b892bd36fb096e6fba213a06da7fab22045e97597db425c724f2bbd6c99a3c295e1e73f3e4de78592289f38431049e1277ca0ae + languageName: node + linkType: hard + +"svg-parser@npm:^2.0.2": version: 2.0.4 resolution: "svg-parser@npm:2.0.4" checksum: b3de6653048212f2ae7afe4a423e04a76ec6d2d06e1bf7eacc618a7c5f7df7faa5105561c57b94579ec831fbbdbf5f190ba56a9205ff39ed13eabdf8ab086ddf @@ -18327,7 +19198,7 @@ __metadata: languageName: node linkType: hard -"symbol-tree@npm:^3.2.2": +"symbol-tree@npm:^3.2.4": version: 3.2.4 resolution: "symbol-tree@npm:3.2.4" checksum: 6e8fc7e1486b8b54bea91199d9535bb72f10842e40c79e882fc94fb7b14b89866adf2fd79efa5ebb5b658bc07fb459ccce5ac0e99ef3d72f474e74aaf284029d @@ -18341,15 +19212,16 @@ __metadata: languageName: node linkType: hard -"table@npm:^5.2.3": - version: 5.4.6 - resolution: "table@npm:5.4.6" +"table@npm:^6.0.9": + version: 6.8.2 + resolution: "table@npm:6.8.2" dependencies: - ajv: ^6.10.2 - lodash: ^4.17.14 - slice-ansi: ^2.1.0 - string-width: ^3.0.0 - checksum: 9e35d3efa788edc17237eef8852f8e4b9178efd65a7d115141777b2ee77df4b7796c05f4ed3712d858f98894ac5935a481ceeb6dcb9895e2f67a61cce0e63b6c + ajv: ^8.0.1 + lodash.truncate: ^4.4.2 + slice-ansi: ^4.0.0 + string-width: ^4.2.3 + strip-ansi: ^6.0.1 + checksum: 61188652f53a980d1759ca460ca8dea5c5322aece3210457e7084882f053c2b6a870041295e08a82cb1d676e31b056406845d94b0abf3c79a4b104777bec413b languageName: node linkType: hard @@ -18361,8 +19233,8 @@ __metadata: linkType: hard "tar@npm:^6.0.2, tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.2.0 - resolution: "tar@npm:6.2.0" + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: ^2.0.0 fs-minipass: ^2.0.0 @@ -18370,26 +19242,54 @@ __metadata: minizlib: ^2.1.1 mkdirp: ^1.0.3 yallist: ^4.0.0 - checksum: db4d9fe74a2082c3a5016630092c54c8375ff3b280186938cfd104f2e089c4fd9bad58688ef6be9cf186a889671bf355c7cda38f09bbf60604b281715ca57f5c + checksum: f1322768c9741a25356c11373bce918483f40fa9a25c69c59410c8a1247632487edef5fe76c5f12ac51a6356d2f1829e96d2bc34098668a2fc34d76050ac2b6c languageName: node linkType: hard -"terser-webpack-plugin@npm:2.3.8": - version: 2.3.8 - resolution: "terser-webpack-plugin@npm:2.3.8" +"temp-dir@npm:^1.0.0": + version: 1.0.0 + resolution: "temp-dir@npm:1.0.0" + checksum: cb2b58ddfb12efa83e939091386ad73b425c9a8487ea0095fe4653192a40d49184a771a1beba99045fbd011e389fd563122d79f54f82be86a55620667e08a6b2 + languageName: node + linkType: hard + +"tempy@npm:^0.3.0": + version: 0.3.0 + resolution: "tempy@npm:0.3.0" + dependencies: + temp-dir: ^1.0.0 + type-fest: ^0.3.1 + unique-string: ^1.0.0 + checksum: f81ef72a7ee6d512439af8d8891e4fc6595309451910d7ac9d760f1242a1f87272b2b97c830c8f74aaa93a3aa550483bb16db17e6345601f64d614d240edc322 + languageName: node + linkType: hard + +"terminal-link@npm:^2.0.0": + version: 2.1.1 + resolution: "terminal-link@npm:2.1.1" + dependencies: + ansi-escapes: ^4.2.1 + supports-hyperlinks: ^2.0.0 + checksum: ce3d2cd3a438c4a9453947aa664581519173ea40e77e2534d08c088ee6dda449eabdbe0a76d2a516b8b73c33262fedd10d5270ccf7576ae316e3db170ce6562f + languageName: node + linkType: hard + +"terser-webpack-plugin@npm:4.2.3": + version: 4.2.3 + resolution: "terser-webpack-plugin@npm:4.2.3" dependencies: - cacache: ^13.0.1 + cacache: ^15.0.5 find-cache-dir: ^3.3.1 - jest-worker: ^25.4.0 - p-limit: ^2.3.0 - schema-utils: ^2.6.6 - serialize-javascript: ^4.0.0 + jest-worker: ^26.5.0 + p-limit: ^3.0.2 + schema-utils: ^3.0.0 + serialize-javascript: ^5.0.1 source-map: ^0.6.1 - terser: ^4.6.12 + terser: ^5.3.4 webpack-sources: ^1.4.3 peerDependencies: webpack: ^4.0.0 || ^5.0.0 - checksum: a772d7d58a4730b619f71c4a8d7cf1fa90ded0d01b4fb9a094437c3380e3c35ce78caa030c2867a10cdd12527dfc2fb46bee949bd067ee0cd41e9890cbd85263 + checksum: ec1b3a85e2645c57e359d5e4831f3e1d78eca2a0c94b156db70eb846ae35b5e6e98ad8784b12e153fc273e57445ce69d017075bbe9fc42868a258ef121f11537 languageName: node linkType: hard @@ -18412,7 +19312,7 @@ __metadata: languageName: node linkType: hard -"terser@npm:^4.1.2, terser@npm:^4.6.12, terser@npm:^4.6.3": +"terser@npm:^4.1.2, terser@npm:^4.6.2, terser@npm:^4.6.3": version: 4.8.1 resolution: "terser@npm:4.8.1" dependencies: @@ -18425,15 +19325,28 @@ __metadata: languageName: node linkType: hard -"test-exclude@npm:^5.2.3": - version: 5.2.3 - resolution: "test-exclude@npm:5.2.3" +"terser@npm:^5.3.4": + version: 5.30.3 + resolution: "terser@npm:5.30.3" + dependencies: + "@jridgewell/source-map": ^0.3.3 + acorn: ^8.8.2 + commander: ^2.20.0 + source-map-support: ~0.5.20 + bin: + terser: bin/terser + checksum: 8c680ed32a948f806fade0969c52aab94b6de174e4a78610f5d3abf9993b161eb19b88b2ceadff09b153858727c02deb6709635e4bfbd519f67d54e0394e2983 + languageName: node + linkType: hard + +"test-exclude@npm:^6.0.0": + version: 6.0.0 + resolution: "test-exclude@npm:6.0.0" dependencies: - glob: ^7.1.3 + "@istanbuljs/schema": ^0.1.2 + glob: ^7.1.4 minimatch: ^3.0.4 - read-pkg-up: ^4.0.0 - require-main-filename: ^2.0.0 - checksum: 3a67bee51b0afb0b7a51b649a7dacd920d929de2b3eccb52fa818f0b0bf2ebfced1d1a77a206b74f95c50f6682e313eedb8000cfdd5ac2f9cc6ed8a32fc4ff2e + checksum: 3b34a3d77165a2cb82b34014b3aba93b1c4637a5011807557dc2f3da826c59975a5ccad765721c4648b39817e3472789f9b0fa98fc854c5c1c7a1e632aacdc28 languageName: node linkType: hard @@ -18444,10 +19357,10 @@ __metadata: languageName: node linkType: hard -"throat@npm:^4.0.0": - version: 4.1.0 - resolution: "throat@npm:4.1.0" - checksum: 43519b0cea6d3b2a8fe056fcbc319e289037be67d2204d4d33513d20d6ee9da6255f7ba8c89e2ec8c97b0f188a910b8666def38d1058d2bf4a39613812c36d98 +"throat@npm:^5.0.0": + version: 5.0.0 + resolution: "throat@npm:5.0.0" + checksum: 031ff7f4431618036c1dedd99c8aa82f5c33077320a8358ed829e84b320783781d1869fe58e8f76e948306803de966f5f7573766a437562c9f5c033297ad2fe2 languageName: node linkType: hard @@ -18468,7 +19381,7 @@ __metadata: languageName: node linkType: hard -"through@npm:^2.3.6, through@npm:^2.3.8": +"through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -18521,15 +19434,6 @@ __metadata: languageName: node linkType: hard -"tmp@npm:^0.0.33": - version: 0.0.33 - resolution: "tmp@npm:0.0.33" - dependencies: - os-tmpdir: ~1.0.2 - checksum: 902d7aceb74453ea02abbf58c203f4a8fc1cead89b60b31e354f74ed5b3fb09ea817f94fb310f884a5d16987dd9fa5a735412a7c2dd088dd3d415aa819ae3a28 - languageName: node - linkType: hard - "tmp@npm:~0.2.1": version: 0.2.1 resolution: "tmp@npm:0.2.1" @@ -18614,7 +19518,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^2.3.3, tough-cookie@npm:^2.3.4, tough-cookie@npm:^2.5.0, tough-cookie@npm:~2.5.0": +"tough-cookie@npm:^2.3.3, tough-cookie@npm:~2.5.0": version: 2.5.0 resolution: "tough-cookie@npm:2.5.0" dependencies: @@ -18624,7 +19528,7 @@ __metadata: languageName: node linkType: hard -"tough-cookie@npm:^4.1.3": +"tough-cookie@npm:^4.0.0, tough-cookie@npm:^4.1.3": version: 4.1.3 resolution: "tough-cookie@npm:4.1.3" dependencies: @@ -18636,12 +19540,12 @@ __metadata: languageName: node linkType: hard -"tr46@npm:^1.0.1": - version: 1.0.1 - resolution: "tr46@npm:1.0.1" +"tr46@npm:^2.1.0": + version: 2.1.0 + resolution: "tr46@npm:2.1.0" dependencies: - punycode: ^2.1.0 - checksum: 96d4ed46bc161db75dbf9247a236ea0bfcaf5758baae6749e92afab0bc5a09cb59af21788ede7e55080f2bf02dce3e4a8f2a484cc45164e29f4b5e68f7cbcc1a + punycode: ^2.1.1 + checksum: ffe6049b9dca3ae329b059aada7f515b0f0064c611b39b51ff6b53897e954650f6f63d9319c6c008d36ead477c7b55e5f64c9dc60588ddc91ff720d64eb710b3 languageName: node linkType: hard @@ -18652,22 +19556,13 @@ __metadata: languageName: node linkType: hard -"trim-newlines@npm:^1.0.0, trim-newlines@npm:^3.0.0": +"trim-newlines@npm:^3.0.0": version: 3.0.1 resolution: "trim-newlines@npm:3.0.1" checksum: b530f3fadf78e570cf3c761fb74fef655beff6b0f84b29209bac6c9622db75ad1417f4a7b5d54c96605dcd72734ad44526fef9f396807b90839449eb543c6206 languageName: node linkType: hard -"true-case-path@npm:^1.0.2": - version: 1.0.3 - resolution: "true-case-path@npm:1.0.3" - dependencies: - glob: ^7.1.2 - checksum: 2e2e3bf37b4b05db2e2a1d60329960a4aa697ad7a89bd97c66f5f4da83977897c29c704276e62bca62d055d8078065bc08a1c7a01f409de11c6592af8b442cbe - languageName: node - linkType: hard - "true-case-path@npm:^2.2.1": version: 2.2.1 resolution: "true-case-path@npm:2.2.1" @@ -18675,6 +19570,13 @@ __metadata: languageName: node linkType: hard +"tryer@npm:^1.0.1": + version: 1.0.1 + resolution: "tryer@npm:1.0.1" + checksum: 1cf14d7f67c79613f054b569bfc9a89c7020d331573a812dfcf7437244e8f8e6eb6893b210cbd9cc217f67c1d72617f89793df231e4fe7d53634ed91cf3a89d1 + languageName: node + linkType: hard + "ts-mock-imports@npm:1.3.7": version: 1.3.7 resolution: "ts-mock-imports@npm:1.3.7" @@ -18685,17 +19587,7 @@ __metadata: languageName: node linkType: hard -"ts-pnp@npm:1.1.6": - version: 1.1.6 - resolution: "ts-pnp@npm:1.1.6" - peerDependenciesMeta: - typescript: - optional: true - checksum: 78a05096ac3b1391bbb8d0b292d76d433f841fb3e698b9bdff961ca1f794e0644e3f0b93d78c6b42dd0e90ef34676cf164855e6010f7b71fed63f2102a387eb9 - languageName: node - linkType: hard - -"ts-pnp@npm:^1.1.6": +"ts-pnp@npm:1.2.0, ts-pnp@npm:^1.1.6": version: 1.2.0 resolution: "ts-pnp@npm:1.2.0" peerDependenciesMeta: @@ -18705,6 +19597,18 @@ __metadata: languageName: node linkType: hard +"tsconfig-paths@npm:^3.15.0": + version: 3.15.0 + resolution: "tsconfig-paths@npm:3.15.0" + dependencies: + "@types/json5": ^0.0.29 + json5: ^1.0.2 + minimist: ^1.2.6 + strip-bom: ^3.0.0 + checksum: 59f35407a390d9482b320451f52a411a256a130ff0e7543d18c6f20afab29ac19fbe55c360a93d6476213cc335a4d76ce90f67df54c4e9037f7d240920832201 + languageName: node + linkType: hard + "tslib@npm:2.5.0": version: 2.5.0 resolution: "tslib@npm:2.5.0" @@ -18799,7 +19703,7 @@ __metadata: languageName: node linkType: hard -"tsutils@npm:^3.0.0, tsutils@npm:^3.21.0": +"tsutils@npm:^3.0.0, tsutils@npm:^3.17.1, tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" dependencies: @@ -18833,6 +19737,15 @@ __metadata: languageName: node linkType: hard +"type-check@npm:^0.4.0, type-check@npm:~0.4.0": + version: 0.4.0 + resolution: "type-check@npm:0.4.0" + dependencies: + prelude-ls: ^1.2.1 + checksum: ec688ebfc9c45d0c30412e41ca9c0cdbd704580eb3a9ccf07b9b576094d7b86a012baebc95681999dd38f4f444afd28504cb3a89f2ef16b31d4ab61a0739025a + languageName: node + linkType: hard + "type-check@npm:~0.3.2": version: 0.3.2 resolution: "type-check@npm:0.3.2" @@ -18856,6 +19769,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.20.2": + version: 0.20.2 + resolution: "type-fest@npm:0.20.2" + checksum: 4fb3272df21ad1c552486f8a2f8e115c09a521ad7a8db3d56d53718d0c907b62c6e9141ba5f584af3f6830d0872c521357e512381f24f7c44acae583ad517d73 + languageName: node + linkType: hard + "type-fest@npm:^0.21.3": version: 0.21.3 resolution: "type-fest@npm:0.21.3" @@ -18863,6 +19783,13 @@ __metadata: languageName: node linkType: hard +"type-fest@npm:^0.3.1": + version: 0.3.1 + resolution: "type-fest@npm:0.3.1" + checksum: 347ff46c2285616635cb59f722e7f396bee81b8988b6fc1f1536b725077f2abf6ccfa22ab7a78e9b6ce7debea0e6614bbf5946cbec6674ec1bde12113af3a65c + languageName: node + linkType: hard + "type-fest@npm:^0.6.0": version: 0.6.0 resolution: "type-fest@npm:0.6.0" @@ -18908,6 +19835,67 @@ __metadata: languageName: node linkType: hard +"typed-array-buffer@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-buffer@npm:1.0.2" + dependencies: + call-bind: ^1.0.7 + es-errors: ^1.3.0 + is-typed-array: ^1.1.13 + checksum: 02ffc185d29c6df07968272b15d5319a1610817916ec8d4cd670ded5d1efe72901541ff2202fcc622730d8a549c76e198a2f74e312eabbfb712ed907d45cbb0b + languageName: node + linkType: hard + +"typed-array-byte-length@npm:^1.0.1": + version: 1.0.1 + resolution: "typed-array-byte-length@npm:1.0.1" + dependencies: + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: f65e5ecd1cf76b1a2d0d6f631f3ea3cdb5e08da106c6703ffe687d583e49954d570cc80434816d3746e18be889ffe53c58bf3e538081ea4077c26a41055b216d + languageName: node + linkType: hard + +"typed-array-byte-offset@npm:^1.0.2": + version: 1.0.2 + resolution: "typed-array-byte-offset@npm:1.0.2" + dependencies: + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + checksum: c8645c8794a621a0adcc142e0e2c57b1823bbfa4d590ad2c76b266aa3823895cf7afb9a893bf6685e18454ab1b0241e1a8d885a2d1340948efa4b56add4b5f67 + languageName: node + linkType: hard + +"typed-array-length@npm:^1.0.6": + version: 1.0.6 + resolution: "typed-array-length@npm:1.0.6" + dependencies: + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-proto: ^1.0.3 + is-typed-array: ^1.1.13 + possible-typed-array-names: ^1.0.0 + checksum: f0315e5b8f0168c29d390ff410ad13e4d511c78e6006df4a104576844812ee447fcc32daab1f3a76c9ef4f64eff808e134528b5b2439de335586b392e9750e5c + languageName: node + linkType: hard + +"typedarray-to-buffer@npm:^3.1.5": + version: 3.1.5 + resolution: "typedarray-to-buffer@npm:3.1.5" + dependencies: + is-typedarray: ^1.0.0 + checksum: 99c11aaa8f45189fcfba6b8a4825fd684a321caa9bd7a76a27cf0c7732c174d198b99f449c52c3818107430b5f41c0ccbbfb75cb2ee3ca4a9451710986d61a60 + languageName: node + linkType: hard + "typedarray@npm:^0.0.6": version: 0.0.6 resolution: "typedarray@npm:0.0.6" @@ -18954,34 +19942,53 @@ __metadata: languageName: node linkType: hard -"unicode-canonical-property-names-ecmascript@npm:^1.0.4": - version: 1.0.4 - resolution: "unicode-canonical-property-names-ecmascript@npm:1.0.4" - checksum: cc1973b18d0e1a151711e5551f87f4b3086c4f542cd5142aa691307d5720fd725fa7d36c24e12e944e108b91c72554237b0c236772d35592839434da5506c40f +"unbox-primitive@npm:^1.0.2": + version: 1.0.2 + resolution: "unbox-primitive@npm:1.0.2" + dependencies: + call-bind: ^1.0.2 + has-bigints: ^1.0.2 + has-symbols: ^1.0.3 + which-boxed-primitive: ^1.0.2 + checksum: b7a1cf5862b5e4b5deb091672ffa579aa274f648410009c81cca63fed3b62b610c4f3b773f912ce545bb4e31edc3138975b5bc777fc6e4817dca51affb6380e9 languageName: node linkType: hard -"unicode-match-property-ecmascript@npm:^1.0.4": - version: 1.0.4 - resolution: "unicode-match-property-ecmascript@npm:1.0.4" +"underscore@npm:1.12.1": + version: 1.12.1 + resolution: "underscore@npm:1.12.1" + checksum: ec327603aa112b99fe9d74cd9bf3b3b7451465a9d2610ceab269a532e3f191650ab017903be34dc86fe406a11d04d8905a3b04dd4c129493e51bee09a3f3074c + languageName: node + linkType: hard + +"unicode-canonical-property-names-ecmascript@npm:^2.0.0": + version: 2.0.0 + resolution: "unicode-canonical-property-names-ecmascript@npm:2.0.0" + checksum: 39be078afd014c14dcd957a7a46a60061bc37c4508ba146517f85f60361acf4c7539552645ece25de840e17e293baa5556268d091ca6762747fdd0c705001a45 + languageName: node + linkType: hard + +"unicode-match-property-ecmascript@npm:^2.0.0": + version: 2.0.0 + resolution: "unicode-match-property-ecmascript@npm:2.0.0" dependencies: - unicode-canonical-property-names-ecmascript: ^1.0.4 - unicode-property-aliases-ecmascript: ^1.0.4 - checksum: 08e269fac71b5ace0f8331df9e87b9b533fe97b00c43ea58de69ae81816581490f846050e0c472279a3e7434524feba99915a93816f90dbbc0a30bcbd082da88 + unicode-canonical-property-names-ecmascript: ^2.0.0 + unicode-property-aliases-ecmascript: ^2.0.0 + checksum: 1f34a7434a23df4885b5890ac36c5b2161a809887000be560f56ad4b11126d433c0c1c39baf1016bdabed4ec54829a6190ee37aa24919aa116dc1a5a8a62965a languageName: node linkType: hard -"unicode-match-property-value-ecmascript@npm:^1.2.0": - version: 1.2.0 - resolution: "unicode-match-property-value-ecmascript@npm:1.2.0" - checksum: 2e663cfec8e2cf317b69613566314979f717034ea8f58a237dd63234795044a87337410064fe839774d71e1d7e12195520e9edd69ed8e28f2a9eb28a2db38595 +"unicode-match-property-value-ecmascript@npm:^2.1.0": + version: 2.1.0 + resolution: "unicode-match-property-value-ecmascript@npm:2.1.0" + checksum: 8d6f5f586b9ce1ed0e84a37df6b42fdba1317a05b5df0c249962bd5da89528771e2d149837cad11aa26bcb84c35355cb9f58a10c3d41fa3b899181ece6c85220 languageName: node linkType: hard -"unicode-property-aliases-ecmascript@npm:^1.0.4": - version: 1.1.0 - resolution: "unicode-property-aliases-ecmascript@npm:1.1.0" - checksum: 1a96dc462d251bb1c5237f7bc77956b29f01cefce7f3e7448430742930961557c3d1515a9669715ebb06209bf01072e2f78ba1627247017daa84346414bc02f1 +"unicode-property-aliases-ecmascript@npm:^2.0.0": + version: 2.1.0 + resolution: "unicode-property-aliases-ecmascript@npm:2.1.0" + checksum: 243524431893649b62cc674d877bd64ef292d6071dd2fd01ab4d5ad26efbc104ffcd064f93f8a06b7e4ec54c172bf03f6417921a0d8c3a9994161fe1f88f815b languageName: node linkType: hard @@ -19054,6 +20061,15 @@ __metadata: languageName: node linkType: hard +"unique-string@npm:^1.0.0": + version: 1.0.0 + resolution: "unique-string@npm:1.0.0" + dependencies: + crypto-random-string: ^1.0.0 + checksum: 588f16bd4ec99b5130f237793d1a5694156adde20460366726573238e41e93b739b87987e863792aeb2392b26f8afb292490ace119c82ed12c46816c9c859f5f + languageName: node + linkType: hard + "universalify@npm:^0.1.0": version: 0.1.2 resolution: "universalify@npm:0.1.2" @@ -19106,7 +20122,7 @@ __metadata: languageName: node linkType: hard -"upath@npm:^1.1.1": +"upath@npm:^1.1.1, upath@npm:^1.1.2, upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" checksum: 4c05c094797cb733193a0784774dbea5b1889d502fc9f0572164177e185e4a59ba7099bf0b0adf945b232e2ac60363f9bf18aac9b2206fb99cbef971a8455445 @@ -19143,20 +20159,20 @@ __metadata: languageName: node linkType: hard -"url-loader@npm:2.3.0": - version: 2.3.0 - resolution: "url-loader@npm:2.3.0" +"url-loader@npm:4.1.1": + version: 4.1.1 + resolution: "url-loader@npm:4.1.1" dependencies: - loader-utils: ^1.2.3 - mime: ^2.4.4 - schema-utils: ^2.5.0 + loader-utils: ^2.0.0 + mime-types: ^2.1.27 + schema-utils: ^3.0.0 peerDependencies: file-loader: "*" - webpack: ^4.0.0 + webpack: ^4.0.0 || ^5.0.0 peerDependenciesMeta: file-loader: optional: true - checksum: c0a8a6e728331e2189a6538373b9ce4b5589389805c4e98a0386ee5d18cc4ba4c5dec5514d8c852dd533b857461c30c3efc135ed07b6b31a96c5a6fb812a4757 + checksum: c1122a992c6cff70a7e56dfc2b7474534d48eb40b2cc75467cde0c6972e7597faf8e43acb4f45f93c2473645dfd803bcbc20960b57544dd1e4c96e77f72ba6fd languageName: node linkType: hard @@ -19204,19 +20220,6 @@ __metadata: languageName: node linkType: hard -"util.promisify@npm:^1.0.0": - version: 1.1.1 - resolution: "util.promisify@npm:1.1.1" - dependencies: - call-bind: ^1.0.0 - define-properties: ^1.1.3 - for-each: ^0.3.3 - has-symbols: ^1.0.1 - object.getownpropertydescriptors: ^2.1.1 - checksum: ea371c30b90576862487ae4efd7182aa5855019549a4019d82629acc2709e8ccb0f38944403eebec622fff8ebb44ac3f46a52d745d5f543d30606132a4905f96 - languageName: node - linkType: hard - "util.promisify@npm:~1.0.0": version: 1.0.1 resolution: "util.promisify@npm:1.0.1" @@ -19279,7 +20282,7 @@ __metadata: languageName: node linkType: hard -"uuid@npm:^8.3.2": +"uuid@npm:^8.3.0, uuid@npm:^8.3.2": version: 8.3.2 resolution: "uuid@npm:8.3.2" bin: @@ -19295,6 +20298,17 @@ __metadata: languageName: node linkType: hard +"v8-to-istanbul@npm:^7.0.0": + version: 7.1.2 + resolution: "v8-to-istanbul@npm:7.1.2" + dependencies: + "@types/istanbul-lib-coverage": ^2.0.1 + convert-source-map: ^1.6.0 + source-map: ^0.7.3 + checksum: e52b48764f55aed62ff87f2b5f710c874f992cd1313eac8f438bf65aeeb0689153d85bb76e39514fd90ba3521d6ebea929a8ae1339b6d7b0cf18fb0ed13d8b40 + languageName: node + linkType: hard + "validate-npm-package-license@npm:^3.0.1": version: 3.0.4 resolution: "validate-npm-package-license@npm:3.0.4" @@ -19344,7 +20358,7 @@ __metadata: languageName: node linkType: hard -"w3c-hr-time@npm:^1.0.1": +"w3c-hr-time@npm:^1.0.2": version: 1.0.2 resolution: "w3c-hr-time@npm:1.0.2" dependencies: @@ -19353,14 +20367,12 @@ __metadata: languageName: node linkType: hard -"w3c-xmlserializer@npm:^1.1.2": - version: 1.1.2 - resolution: "w3c-xmlserializer@npm:1.1.2" +"w3c-xmlserializer@npm:^2.0.0": + version: 2.0.0 + resolution: "w3c-xmlserializer@npm:2.0.0" dependencies: - domexception: ^1.0.1 - webidl-conversions: ^4.0.2 xml-name-validator: ^3.0.0 - checksum: 1683e083d0dfc1529988f8956510a3a26e90738b41c4df0c7eb95283bfbeabeb492308117dcd32afef2a141e2a959ddf10ce562983d91b9f474a530b9dcdd337 + checksum: ae25c51cf71f1fb2516df1ab33a481f83461a117565b95e3d0927432522323f93b1b2846cbb60196d337970c421adb604fc2d0d180c6a47a839da01db5b9973b languageName: node linkType: hard @@ -19416,7 +20428,7 @@ __metadata: languageName: node linkType: hard -"watchpack@npm:^1.6.0": +"watchpack@npm:^1.7.4": version: 1.7.5 resolution: "watchpack@npm:1.7.5" dependencies: @@ -19449,10 +20461,17 @@ __metadata: languageName: node linkType: hard -"webidl-conversions@npm:^4.0.2": - version: 4.0.2 - resolution: "webidl-conversions@npm:4.0.2" - checksum: c93d8dfe908a0140a4ae9c0ebc87a33805b416a33ee638a605b551523eec94a9632165e54632f6d57a39c5f948c4bab10e0e066525e9a4b87a79f0d04fbca374 +"webidl-conversions@npm:^5.0.0": + version: 5.0.0 + resolution: "webidl-conversions@npm:5.0.0" + checksum: ccf1ec2ca7c0b5671e5440ace4a66806ae09c49016ab821481bec0c05b1b82695082dc0a27d1fe9d804d475a408ba0c691e6803fd21be608e710955d4589cd69 + languageName: node + linkType: hard + +"webidl-conversions@npm:^6.1.0": + version: 6.1.0 + resolution: "webidl-conversions@npm:6.1.0" + checksum: 1f526507aa491f972a0c1409d07f8444e1d28778dfa269a9971f2e157182f3d496dc33296e4ed45b157fdb3bf535bb90c90bf10c50dcf1dd6caacb2a34cc84fb languageName: node linkType: hard @@ -19543,7 +20562,7 @@ __metadata: languageName: node linkType: hard -"webpack-sources@npm:^1.1.0, webpack-sources@npm:^1.4.0, webpack-sources@npm:^1.4.1, webpack-sources@npm:^1.4.3": +"webpack-sources@npm:^1.1.0, webpack-sources@npm:^1.3.0, webpack-sources@npm:^1.4.0, webpack-sources@npm:^1.4.1, webpack-sources@npm:^1.4.3": version: 1.4.3 resolution: "webpack-sources@npm:1.4.3" dependencies: @@ -19553,36 +20572,41 @@ __metadata: languageName: node linkType: hard -"webpack@npm:4.42.0": - version: 4.42.0 - resolution: "webpack@npm:4.42.0" +"webpack@npm:4.44.2": + version: 4.44.2 + resolution: "webpack@npm:4.44.2" dependencies: - "@webassemblyjs/ast": 1.8.5 - "@webassemblyjs/helper-module-context": 1.8.5 - "@webassemblyjs/wasm-edit": 1.8.5 - "@webassemblyjs/wasm-parser": 1.8.5 - acorn: ^6.2.1 + "@webassemblyjs/ast": 1.9.0 + "@webassemblyjs/helper-module-context": 1.9.0 + "@webassemblyjs/wasm-edit": 1.9.0 + "@webassemblyjs/wasm-parser": 1.9.0 + acorn: ^6.4.1 ajv: ^6.10.2 ajv-keywords: ^3.4.1 chrome-trace-event: ^1.0.2 - enhanced-resolve: ^4.1.0 + enhanced-resolve: ^4.3.0 eslint-scope: ^4.0.3 json-parse-better-errors: ^1.0.2 loader-runner: ^2.4.0 loader-utils: ^1.2.3 memory-fs: ^0.4.1 micromatch: ^3.1.10 - mkdirp: ^0.5.1 + mkdirp: ^0.5.3 neo-async: ^2.6.1 node-libs-browser: ^2.2.1 schema-utils: ^1.0.0 tapable: ^1.1.3 terser-webpack-plugin: ^1.4.3 - watchpack: ^1.6.0 + watchpack: ^1.7.4 webpack-sources: ^1.4.1 + peerDependenciesMeta: + webpack-cli: + optional: true + webpack-command: + optional: true bin: webpack: bin/webpack.js - checksum: c297519655f431d749abf0383a0c565d3fdad14baef70fc96b09285f1da6cdad22b24f7f1974ef07314f0d088235ad2e26090ebd497fb4b7fbe5e8372117d734 + checksum: 3d42ee6af7a0ff14fc00136d02f4a36381fd5b6ad0636b95a8b83e6d99bc7e02f888f4994c095ae986e567033fe7bb1d445e27afe49d2872b8fe5c3a57d20de6 languageName: node linkType: hard @@ -19613,7 +20637,7 @@ __metadata: languageName: node linkType: hard -"whatwg-encoding@npm:^1.0.1, whatwg-encoding@npm:^1.0.3, whatwg-encoding@npm:^1.0.5": +"whatwg-encoding@npm:^1.0.5": version: 1.0.5 resolution: "whatwg-encoding@npm:1.0.5" dependencies: @@ -19622,14 +20646,21 @@ __metadata: languageName: node linkType: hard -"whatwg-fetch@npm:>=0.10.0, whatwg-fetch@npm:^3.0.0": +"whatwg-fetch@npm:>=0.10.0": version: 3.6.2 resolution: "whatwg-fetch@npm:3.6.2" checksum: ee976b7249e7791edb0d0a62cd806b29006ad7ec3a3d89145921ad8c00a3a67e4be8f3fb3ec6bc7b58498724fd568d11aeeeea1f7827e7e1e5eae6c8a275afed languageName: node linkType: hard -"whatwg-mimetype@npm:^2.1.0, whatwg-mimetype@npm:^2.2.0, whatwg-mimetype@npm:^2.3.0": +"whatwg-fetch@npm:^3.4.1": + version: 3.6.20 + resolution: "whatwg-fetch@npm:3.6.20" + checksum: c58851ea2c4efe5c2235f13450f426824cf0253c1d45da28f45900290ae602a20aff2ab43346f16ec58917d5562e159cd691efa368354b2e82918c2146a519c5 + languageName: node + linkType: hard + +"whatwg-mimetype@npm:^2.3.0": version: 2.3.0 resolution: "whatwg-mimetype@npm:2.3.0" checksum: 23eb885940bcbcca4ff841c40a78e9cbb893ec42743993a42bf7aed16085b048b44b06f3402018931687153550f9a32d259dfa524e4f03577ab898b6965e5383 @@ -19646,25 +20677,14 @@ __metadata: languageName: node linkType: hard -"whatwg-url@npm:^6.4.1": - version: 6.5.0 - resolution: "whatwg-url@npm:6.5.0" - dependencies: - lodash.sortby: ^4.7.0 - tr46: ^1.0.1 - webidl-conversions: ^4.0.2 - checksum: a10bd5e29f4382cd19789c2a7bbce25416e606b6fefc241c7fe34a2449de5bc5709c165bd13634eda433942d917ca7386a52841780b82dc37afa8141c31a8ebd - languageName: node - linkType: hard - -"whatwg-url@npm:^7.0.0": - version: 7.1.0 - resolution: "whatwg-url@npm:7.1.0" +"whatwg-url@npm:^8.0.0, whatwg-url@npm:^8.5.0": + version: 8.7.0 + resolution: "whatwg-url@npm:8.7.0" dependencies: - lodash.sortby: ^4.7.0 - tr46: ^1.0.1 - webidl-conversions: ^4.0.2 - checksum: fecb07c87290b47d2ec2fb6d6ca26daad3c9e211e0e531dd7566e7ff95b5b3525a57d4f32640ad4adf057717e0c215731db842ad761e61d947e81010e05cf5fd + lodash: ^4.7.0 + tr46: ^2.1.0 + webidl-conversions: ^6.1.0 + checksum: a87abcc6cefcece5311eb642858c8fdb234e51ec74196bfacf8def2edae1bfbffdf6acb251646ed6301f8cee44262642d8769c707256125a91387e33f405dd1e languageName: node linkType: hard @@ -19681,10 +20701,35 @@ __metadata: languageName: node linkType: hard -"which-module@npm:^1.0.0": - version: 1.0.0 - resolution: "which-module@npm:1.0.0" - checksum: 98434f7deb36350cb543c1f15612188541737e1f12d39b23b1c371dff5cf4aa4746210f2bdec202d5fe9da8682adaf8e3f7c44c520687d30948cfc59d5534edb +"which-builtin-type@npm:^1.1.3": + version: 1.1.3 + resolution: "which-builtin-type@npm:1.1.3" + dependencies: + function.prototype.name: ^1.1.5 + has-tostringtag: ^1.0.0 + is-async-function: ^2.0.0 + is-date-object: ^1.0.5 + is-finalizationregistry: ^1.0.2 + is-generator-function: ^1.0.10 + is-regex: ^1.1.4 + is-weakref: ^1.0.2 + isarray: ^2.0.5 + which-boxed-primitive: ^1.0.2 + which-collection: ^1.0.1 + which-typed-array: ^1.1.9 + checksum: 43730f7d8660ff9e33d1d3f9f9451c4784265ee7bf222babc35e61674a11a08e1c2925019d6c03154fcaaca4541df43abe35d2720843b9b4cbcebdcc31408f36 + languageName: node + linkType: hard + +"which-collection@npm:^1.0.1": + version: 1.0.2 + resolution: "which-collection@npm:1.0.2" + dependencies: + is-map: ^2.0.3 + is-set: ^2.0.3 + is-weakmap: ^2.0.2 + is-weakset: ^2.0.3 + checksum: c51821a331624c8197916598a738fc5aeb9a857f1e00d89f5e4c03dc7c60b4032822b8ec5696d28268bb83326456a8b8216344fb84270d18ff1d7628051879d9 languageName: node linkType: hard @@ -19695,7 +20740,20 @@ __metadata: languageName: node linkType: hard -"which@npm:^1.2.9, which@npm:^1.3.0, which@npm:^1.3.1": +"which-typed-array@npm:^1.1.14, which-typed-array@npm:^1.1.15, which-typed-array@npm:^1.1.9": + version: 1.1.15 + resolution: "which-typed-array@npm:1.1.15" + dependencies: + available-typed-arrays: ^1.0.7 + call-bind: ^1.0.7 + for-each: ^0.3.3 + gopd: ^1.0.1 + has-tostringtag: ^1.0.2 + checksum: 65227dcbfadf5677aacc43ec84356d17b5500cb8b8753059bb4397de5cd0c2de681d24e1a7bd575633f976a95f88233abfd6549c2105ef4ebd58af8aa1807c75 + languageName: node + linkType: hard + +"which@npm:^1.2.9, which@npm:^1.3.1": version: 1.3.1 resolution: "which@npm:1.3.1" dependencies: @@ -19717,7 +20775,7 @@ __metadata: languageName: node linkType: hard -"wide-align@npm:^1.1.2, wide-align@npm:^1.1.5": +"wide-align@npm:^1.1.5": version: 1.1.5 resolution: "wide-align@npm:1.1.5" dependencies: @@ -19733,172 +20791,190 @@ __metadata: languageName: node linkType: hard -"workbox-background-sync@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-background-sync@npm:4.3.1" +"workbox-background-sync@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-background-sync@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: 25564fb0adc36396ea60308c4f8184cffe245eca9bd931a8154fc25736297071448be43de85b0b477da74e61410cdf60a295b25d4d3e780fa36b73ef983cc678 + workbox-core: ^5.1.4 + checksum: 14655d0254813d2580935c88fe4768eb4794158a3c0700505aa06784dcd8d7498563e8b55152f0a4afb609163e76787a3a3eb61813b810bd76830c866d6ceb9e languageName: node linkType: hard -"workbox-broadcast-update@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-broadcast-update@npm:4.3.1" +"workbox-broadcast-update@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-broadcast-update@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: f62035645d37b0763f09a5b688dbdba14b28ac69c2b8d609b6a68be888c8a9c384186cde01fc1c41ac9d45e383320a6cf743a9209d7390d97d27c61c5ace64f3 + workbox-core: ^5.1.4 + checksum: b56df2fde652c2efa8afbb8880562aaac6932be313ddcbbb688bb48beeb3164c928a644407f359168789a31592c765f63526608afe6cd803ac89402f786064d1 languageName: node linkType: hard -"workbox-build@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-build@npm:4.3.1" +"workbox-build@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-build@npm:5.1.4" dependencies: - "@babel/runtime": ^7.3.4 - "@hapi/joi": ^15.0.0 + "@babel/core": ^7.8.4 + "@babel/preset-env": ^7.8.4 + "@babel/runtime": ^7.8.4 + "@hapi/joi": ^15.1.0 + "@rollup/plugin-node-resolve": ^7.1.1 + "@rollup/plugin-replace": ^2.3.1 + "@surma/rollup-plugin-off-main-thread": ^1.1.1 common-tags: ^1.8.0 - fs-extra: ^4.0.2 - glob: ^7.1.3 - lodash.template: ^4.4.0 - pretty-bytes: ^5.1.0 + fast-json-stable-stringify: ^2.1.0 + fs-extra: ^8.1.0 + glob: ^7.1.6 + lodash.template: ^4.5.0 + pretty-bytes: ^5.3.0 + rollup: ^1.31.1 + rollup-plugin-babel: ^4.3.3 + rollup-plugin-terser: ^5.3.1 + source-map: ^0.7.3 + source-map-url: ^0.4.0 stringify-object: ^3.3.0 strip-comments: ^1.0.2 - workbox-background-sync: ^4.3.1 - workbox-broadcast-update: ^4.3.1 - workbox-cacheable-response: ^4.3.1 - workbox-core: ^4.3.1 - workbox-expiration: ^4.3.1 - workbox-google-analytics: ^4.3.1 - workbox-navigation-preload: ^4.3.1 - workbox-precaching: ^4.3.1 - workbox-range-requests: ^4.3.1 - workbox-routing: ^4.3.1 - workbox-strategies: ^4.3.1 - workbox-streams: ^4.3.1 - workbox-sw: ^4.3.1 - workbox-window: ^4.3.1 - checksum: 3bf0f400512b621a67f2f7ab9f1beb7964c12cb12186da1a2a51ec456a8b63e0c9a2e0fbd31c003aecd2779fb4061e8cad73b8fe94e790e141aa110169d6504b - languageName: node - linkType: hard - -"workbox-cacheable-response@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-cacheable-response@npm:4.3.1" + tempy: ^0.3.0 + upath: ^1.2.0 + workbox-background-sync: ^5.1.4 + workbox-broadcast-update: ^5.1.4 + workbox-cacheable-response: ^5.1.4 + workbox-core: ^5.1.4 + workbox-expiration: ^5.1.4 + workbox-google-analytics: ^5.1.4 + workbox-navigation-preload: ^5.1.4 + workbox-precaching: ^5.1.4 + workbox-range-requests: ^5.1.4 + workbox-routing: ^5.1.4 + workbox-strategies: ^5.1.4 + workbox-streams: ^5.1.4 + workbox-sw: ^5.1.4 + workbox-window: ^5.1.4 + checksum: 873833d0ea5c39c3f9adae9b2cd8ff33c013ff57f189dbec94d4d02917281495f38bbfa508d24425176ea8d31d6a27590658c83c30d44d9d5a9f4eb4d0798694 + languageName: node + linkType: hard + +"workbox-cacheable-response@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-cacheable-response@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: c281f40388891a7920b7ecf73a61b0b9274174c17d703ef2a4c6ecb2e0a277ff447c24205594e50a922adca40de39767ebc34c79cfba9040abf10e4b879142b5 + workbox-core: ^5.1.4 + checksum: 3d8940dbee11880fdd86d76f85c063cf0a42d722be828332acf2f69ff5eaaedc8a0d779e44175adba4e8485f98392052539b2126df79125cebcec57dea0bee3c languageName: node linkType: hard -"workbox-core@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-core@npm:4.3.1" - checksum: c3e31bb24c4bfbc2be129c7745c12512c6e061dfa032b0dbe3620aa1b15fe12df433c6f39f17bcaebef2d2826a5ca18760b778d12c86876295e2cf121725ca09 +"workbox-core@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-core@npm:5.1.4" + checksum: 6062bc3131bb7fcf1922be619cbc28ba528b033ba18acced5e42eb62b6c0a763814e905106c081c1c100a5d520ef104957e99e592e5e954767df76db49a7c874 languageName: node linkType: hard -"workbox-expiration@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-expiration@npm:4.3.1" +"workbox-expiration@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-expiration@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: c1bfa47278720d1729a88562b1e2a5d0d7d27d6b625190ad6db2a3518ad4907833b1b9182a6e7dae687e4f12e13047b102b1b82f6fe9529523c82e74729d023a + workbox-core: ^5.1.4 + checksum: c4648a008d19ee1281d5d588e10f14bd01530d8601c6ebf27e63b109663530fd381709539f1dd8a32e75d68a04e40e5f31ec6fbcc9ea052ee39000a2d76ade50 languageName: node linkType: hard -"workbox-google-analytics@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-google-analytics@npm:4.3.1" +"workbox-google-analytics@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-google-analytics@npm:5.1.4" dependencies: - workbox-background-sync: ^4.3.1 - workbox-core: ^4.3.1 - workbox-routing: ^4.3.1 - workbox-strategies: ^4.3.1 - checksum: 225cea09758767bba9be553578e5d6f509ef055149a07df0b366c6f17dcd98220a939e48d1cacb3132f1d4d2e896d093a6ee00744498522b3aa25d48e9f21eb4 + workbox-background-sync: ^5.1.4 + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + workbox-strategies: ^5.1.4 + checksum: 2783e93f8a5aeccc038f51a9960c05aebd104fd8d113b5fd78a09bac2da8ed8e2be4c9fd7d8a6751682301d6b5e36ba055240a74a3591b4e887aabb2784cd531 languageName: node linkType: hard -"workbox-navigation-preload@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-navigation-preload@npm:4.3.1" +"workbox-navigation-preload@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-navigation-preload@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: 50c2bc59b66f980e5d5c9798f8e8883a6fd5af982ccfd4938e17de126cb2f4a614b143e3cff8862e140ccb7db3ce695162c98be8cf798d69e41266b20f74a74c + workbox-core: ^5.1.4 + checksum: ed6b19f063f17e2dd12ef08594ea338fcf96d994ea8f7d9b2987099cb08a890c73f139a23b68c9c5523308fba4634f24aca079deb7d00684c8d76fdfb07b0fc9 languageName: node linkType: hard -"workbox-precaching@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-precaching@npm:4.3.1" +"workbox-precaching@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-precaching@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: afac7991d4f1d660d0fa97437f18a3e67ed978991c4f1f159b0bb3d267f3d6b6aa34f0a7f505e298acb0d66af33224b0f1b8eac0f05c39a319d1a3b4203c6ee5 + workbox-core: ^5.1.4 + checksum: 5593c5b9c3c928bb5d3b4c998625be610d05a3b55523e5abb0fc5f12ff2e32412114e933e60d54ba9e2661fa3cbbbab7e11f91c7170742cfe9525437d1c44ae8 languageName: node linkType: hard -"workbox-range-requests@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-range-requests@npm:4.3.1" +"workbox-range-requests@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-range-requests@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: bf0a2daebc4611c97f83c068911f7724e8c92c7270ee40f1e815fc227eb29a920fced0ce88421b413ca688574d1b5731bc45b0c34a208f9e0eace4d2b302eb5f + workbox-core: ^5.1.4 + checksum: c67b467023e85a45599c411079907585c4d4b7aab77205dd905cd0d8b1487aa248469bc2f89045e8bd4a08eed4ede14795fc9089d01beff65ff3c6f2f1deff45 languageName: node linkType: hard -"workbox-routing@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-routing@npm:4.3.1" +"workbox-routing@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-routing@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: fb8bc5f67246c418b6fd15d9763a4200633cc099edb13d4a266ddf8c23f5a0c1fe2e2fc8380928eb1c1ee0d821d677355706e294113650638bd809c589ae24d4 + workbox-core: ^5.1.4 + checksum: 4199a02b433eb645dfcaf2a5056a04d79f337b6f368b1ab5aa18262857835d4b995536062c294d6f4db6da236235b5736af4b29d0ea1b0c3f0db339b04d3cd40 languageName: node linkType: hard -"workbox-strategies@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-strategies@npm:4.3.1" +"workbox-strategies@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-strategies@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: dc49af50ddc9c240160f997e195cbe57efe8cb764eb2652174778bc44f3697b9680784a00af2c55ad56d41ed507c4140c4985c2f74ee9d4b3f68e99c889a54f4 + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + checksum: 6ed247bfc0037331043cd0e772c6fd8d48e487875fac75d6692eb3936536ca2d4ac5ac9d12ec9b0ad5eefd4a69afd1ad2a993829ce3a373390880a019fd33d3d languageName: node linkType: hard -"workbox-streams@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-streams@npm:4.3.1" +"workbox-streams@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-streams@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: 7a06e4a10eb30ed6ba90ed6647049355db251d970e9f3d1e3f4d20b4ca9d25082275301d31c0f506761bbc494956cd542c073db67d6a6bb4ff069f5e77bce510 + workbox-core: ^5.1.4 + workbox-routing: ^5.1.4 + checksum: daaedb22dae6eb4723e7a21d758854adb36b75f1fa2453a914b6768628d91555e3db76fccb70a101f5cf1a39056e783eab1c8b0f4a59649f7ef4fad173c6f7d3 languageName: node linkType: hard -"workbox-sw@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-sw@npm:4.3.1" - checksum: 349a9b1a3c9b57dc1925a8709f9af3e90d6c6b8e56f10c88c70236abdf5ba8e3a66f8c004356fc1cb7c24cfabf0f162b132930454e1fb390d29e2ce46696f3a5 +"workbox-sw@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-sw@npm:5.1.4" + checksum: eda970f62c26715b806828cab3000240843bab2e6577c341ccd30747a77a60d23f4f08d8d85fba680bfefa95c673c4d48a62a969a2540916dcf6506c627c69cc languageName: node linkType: hard -"workbox-webpack-plugin@npm:4.3.1": - version: 4.3.1 - resolution: "workbox-webpack-plugin@npm:4.3.1" +"workbox-webpack-plugin@npm:5.1.4": + version: 5.1.4 + resolution: "workbox-webpack-plugin@npm:5.1.4" dependencies: - "@babel/runtime": ^7.0.0 - json-stable-stringify: ^1.0.1 - workbox-build: ^4.3.1 + "@babel/runtime": ^7.5.5 + fast-json-stable-stringify: ^2.0.0 + source-map-url: ^0.4.0 + upath: ^1.1.2 + webpack-sources: ^1.3.0 + workbox-build: ^5.1.4 peerDependencies: - webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 - checksum: 7282d849d96c90a82b985784279d28bf1a95534429b3f95cc9f028142f10cea78e13a608f7e29a545e4f82cbe7b081a6e82ad57131dc09604c239a4b53a7a860 + webpack: ^4.0.0 + checksum: 7a9093d4ccfedc27ee6716443bcb7ce12d1f92831f48d09e6cf829a62d2ba7948a84ed38964923136d6b296e8f60bda359645a82c5a19e2c5a8e8aab6dae0a55 languageName: node linkType: hard -"workbox-window@npm:^4.3.1": - version: 4.3.1 - resolution: "workbox-window@npm:4.3.1" +"workbox-window@npm:^5.1.4": + version: 5.1.4 + resolution: "workbox-window@npm:5.1.4" dependencies: - workbox-core: ^4.3.1 - checksum: 60b854fb0febdde236b0285eb050131043446a0c011629f8480224b1cee3a2f9f13f4c851f4a30dd8a76aa58503436c16f17662ef0eb40d0e1c630842165e718 + workbox-core: ^5.1.4 + checksum: bd5bc967ea1202c555db4360892518f5479027d05e4bd02fd38ebef3faf6605ee7e3887225e0920624cd2685e5217c3c4bd43a7d458860d186400c12f410df5b languageName: node linkType: hard @@ -19920,16 +20996,6 @@ __metadata: languageName: node linkType: hard -"wrap-ansi@npm:^2.0.0": - version: 2.1.0 - resolution: "wrap-ansi@npm:2.1.0" - dependencies: - string-width: ^1.0.1 - strip-ansi: ^3.0.1 - checksum: 2dacd4b3636f7a53ee13d4d0fe7fa2ed9ad81e9967e17231924ea88a286ec4619a78288de8d41881ee483f4449ab2c0287cde8154ba1bd0126c10271101b2ee3 - languageName: node - linkType: hard - "wrap-ansi@npm:^5.1.0": version: 5.1.0 resolution: "wrap-ansi@npm:5.1.0" @@ -19970,36 +21036,19 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:2.4.1": - version: 2.4.1 - resolution: "write-file-atomic@npm:2.4.1" +"write-file-atomic@npm:^3.0.0": + version: 3.0.3 + resolution: "write-file-atomic@npm:3.0.3" dependencies: - graceful-fs: ^4.1.11 imurmurhash: ^0.1.4 + is-typedarray: ^1.0.0 signal-exit: ^3.0.2 - checksum: 9a032212214fb281fa7004e53115dfe38cd6f7191902ac7b691524c42f565f9083f2bb810aa30936b25559ed9f9b1772a2e385c29e5e7e4ef1253388610acdf1 - languageName: node - linkType: hard - -"write@npm:1.0.3": - version: 1.0.3 - resolution: "write@npm:1.0.3" - dependencies: - mkdirp: ^0.5.1 - checksum: 6496197ceb2d6faeeb8b5fe2659ca804e801e4989dff9fb8a66fe76179ce4ccc378c982ef906733caea1220c8dbe05a666d82127959ac4456e70111af8b8df73 + typedarray-to-buffer: ^3.1.5 + checksum: c55b24617cc61c3a4379f425fc62a386cc51916a9b9d993f39734d005a09d5a4bb748bc251f1304e7abd71d0a26d339996c275955f527a131b1dcded67878280 languageName: node linkType: hard -"ws@npm:^5.2.0": - version: 5.2.3 - resolution: "ws@npm:5.2.3" - dependencies: - async-limiter: ~1.0.0 - checksum: bdb2223a40c2c68cf91b25a6c9b8c67d5275378ec6187f343314d3df7530e55b77cb9fe79fb1c6a9758389ac5aefc569d24236924b5c65c5dbbaff409ef739fc - languageName: node - linkType: hard - -"ws@npm:^6.1.2, ws@npm:^6.2.1": +"ws@npm:^6.2.1": version: 6.2.2 resolution: "ws@npm:6.2.2" dependencies: @@ -20008,6 +21057,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^7.4.6": + version: 7.5.9 + resolution: "ws@npm:7.5.9" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: c3c100a181b731f40b7f2fddf004aa023f79d64f489706a28bc23ff88e87f6a64b3c6651fbec3a84a53960b75159574d7a7385709847a62ddb7ad6af76f49138 + languageName: node + linkType: hard + "xml-name-validator@npm:^3.0.0": version: 3.0.0 resolution: "xml-name-validator@npm:3.0.0" @@ -20015,22 +21079,13 @@ __metadata: languageName: node linkType: hard -"xmlchars@npm:^2.1.1": +"xmlchars@npm:^2.2.0": version: 2.2.0 resolution: "xmlchars@npm:2.2.0" checksum: 8c70ac94070ccca03f47a81fcce3b271bd1f37a591bf5424e787ae313fcb9c212f5f6786e1fa82076a2c632c0141552babcd85698c437506dfa6ae2d58723062 languageName: node linkType: hard -"xregexp@npm:^4.3.0": - version: 4.4.1 - resolution: "xregexp@npm:4.4.1" - dependencies: - "@babel/runtime-corejs3": ^7.12.1 - checksum: 134d70116655f0de90725a0d2aaf73b2a69f8b4cd7f1908e394c7ff4de53819a0a2d9595e1722d71334a33d9392071b1f983f5954c57d83ab3e451116d9f8499 - languageName: node - linkType: hard - "xtend@npm:^4.0.0, xtend@npm:~4.0.1": version: 4.0.2 resolution: "xtend@npm:4.0.2" @@ -20038,13 +21093,6 @@ __metadata: languageName: node linkType: hard -"y18n@npm:^3.2.1": - version: 3.2.2 - resolution: "y18n@npm:3.2.2" - checksum: 6154fd7544f8bbf5b18cdf77692ed88d389be49c87238ecb4e0d6a5276446cd2a5c29cc4bdbdddfc7e4e498b08df9d7e38df4a1453cf75eecfead392246ea74a - languageName: node - linkType: hard - "y18n@npm:^4.0.0": version: 4.0.3 resolution: "y18n@npm:4.0.3" @@ -20073,7 +21121,7 @@ __metadata: languageName: node linkType: hard -"yaml@npm:^1.7.2": +"yaml@npm:^1.10.0": version: 1.10.2 resolution: "yaml@npm:1.10.2" checksum: ce4ada136e8a78a0b08dc10b4b900936912d15de59905b2bf415b4d33c63df1d555d23acb2a41b23cf9fb5da41c256441afca3d6509de7247daa062fd2c5ea5f @@ -20103,6 +21151,16 @@ __metadata: languageName: node linkType: hard +"yargs-parser@npm:^18.1.2": + version: 18.1.3 + resolution: "yargs-parser@npm:18.1.3" + dependencies: + camelcase: ^5.0.0 + decamelize: ^1.2.0 + checksum: 60e8c7d1b85814594d3719300ecad4e6ae3796748b0926137bfec1f3042581b8646d67e83c6fc80a692ef08b8390f21ddcacb9464476c39bbdf52e34961dd4d9 + languageName: node + linkType: hard + "yargs-parser@npm:^20.2.2, yargs-parser@npm:^20.2.3": version: 20.2.9 resolution: "yargs-parser@npm:20.2.9" @@ -20117,17 +21175,7 @@ __metadata: languageName: node linkType: hard -"yargs-parser@npm:^5.0.1": - version: 5.0.1 - resolution: "yargs-parser@npm:5.0.1" - dependencies: - camelcase: ^3.0.0 - object.assign: ^4.1.0 - checksum: 8eff7f3653afc9185cb917ee034d189c1ba4bc0fd5005c9588442e25557e9bf69c7331663a6f9a2bb897cd4c1544ba9675ed3335133e19e660a3086fedc259db - languageName: node - linkType: hard - -"yargs@npm:^13.3.0, yargs@npm:^13.3.2": +"yargs@npm:^13.3.2": version: 13.3.2 resolution: "yargs@npm:13.3.2" dependencies: @@ -20145,6 +21193,25 @@ __metadata: languageName: node linkType: hard +"yargs@npm:^15.4.1": + version: 15.4.1 + resolution: "yargs@npm:15.4.1" + dependencies: + cliui: ^6.0.0 + decamelize: ^1.2.0 + find-up: ^4.1.0 + get-caller-file: ^2.0.1 + require-directory: ^2.1.1 + require-main-filename: ^2.0.0 + set-blocking: ^2.0.0 + string-width: ^4.2.0 + which-module: ^2.0.0 + y18n: ^4.0.0 + yargs-parser: ^18.1.2 + checksum: 40b974f508d8aed28598087720e086ecd32a5fd3e945e95ea4457da04ee9bdb8bdd17fd91acff36dc5b7f0595a735929c514c40c402416bbb87c03f6fb782373 + languageName: node + linkType: hard + "yargs@npm:^17.0.0": version: 17.0.1 resolution: "yargs@npm:17.0.1" @@ -20175,27 +21242,6 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^7.0.0": - version: 7.1.2 - resolution: "yargs@npm:7.1.2" - dependencies: - camelcase: ^3.0.0 - cliui: ^3.2.0 - decamelize: ^1.1.1 - get-caller-file: ^1.0.1 - os-locale: ^1.4.0 - read-pkg-up: ^1.0.1 - require-directory: ^2.1.1 - require-main-filename: ^1.0.1 - set-blocking: ^2.0.0 - string-width: ^1.0.2 - which-module: ^1.0.0 - y18n: ^3.2.1 - yargs-parser: ^5.0.1 - checksum: 0c330ce1338cd9f293157bf8955af6833ae59032ab1bc936510ce7a216de9bb65b05b39a82ff0e7359bfb643342cc05de5049ce50ee9404b0818f65911fb59a5 - languageName: node - linkType: hard - "yauzl@npm:^2.10.0": version: 2.10.0 resolution: "yauzl@npm:2.10.0" @@ -20205,3 +21251,10 @@ __metadata: checksum: 7f21fe0bbad6e2cb130044a5d1d0d5a0e5bf3d8d4f8c4e6ee12163ce798fee3de7388d22a7a0907f563ac5f9d40f8699a223d3d5c1718da90b0156da6904022b languageName: node linkType: hard + +"yocto-queue@npm:^0.1.0": + version: 0.1.0 + resolution: "yocto-queue@npm:0.1.0" + checksum: f77b3d8d00310def622123df93d4ee654fc6a0096182af8bd60679ddcdfb3474c56c6c7190817c84a2785648cdee9d721c0154eb45698c62176c322fb46fc700 + languageName: node + linkType: hard diff --git a/services/ws/event_source_test.go b/services/ws/event_source_test.go index d02b199939..172f74ce7a 100644 --- a/services/ws/event_source_test.go +++ b/services/ws/event_source_test.go @@ -7,11 +7,14 @@ package ws import ( "database/sql" "fmt" + "io/ioutil" + "sort" "sync" "time" "git.arvados.org/arvados.git/sdk/go/arvados" "git.arvados.org/arvados.git/sdk/go/ctxlog" + "github.com/ghodss/yaml" "github.com/prometheus/client_golang/prometheus" check "gopkg.in/check.v1" ) @@ -41,6 +44,18 @@ func testDB() *sql.DB { } func (*eventSourceSuite) TestEventSource(c *check.C) { + var logfixtures map[string]struct { + ID int + } + yamldata, err := ioutil.ReadFile("../api/test/fixtures/logs.yml") + c.Assert(err, check.IsNil) + c.Assert(yaml.Unmarshal(yamldata, &logfixtures), check.IsNil) + var logIDs []int + for _, logfixture := range logfixtures { + logIDs = append(logIDs, logfixture.ID) + } + sort.Ints(logIDs) + cfg := testDBConfig() db := testDB() pges := &pgEventSource{ @@ -61,8 +76,8 @@ func (*eventSourceSuite) TestEventSource(c *check.C) { done := make(chan bool, 1) go func() { - for i := range sinks { - _, err := db.Exec(fmt.Sprintf(`NOTIFY logs, '%d'`, i)) + for _, id := range logIDs { + _, err := db.Exec(fmt.Sprintf(`NOTIFY logs, '%d'`, id)) if err != nil { done <- true c.Fatal(err) @@ -77,17 +92,13 @@ func (*eventSourceSuite) TestEventSource(c *check.C) { go func(si int, s eventSink) { defer wg.Done() defer sinks[si].Stop() - for i := 0; i <= si; i++ { + for _, logID := range logIDs { ev := <-sinks[si].Channel() - c.Logf("sink %d received event %d", si, i) - c.Check(ev.LogID, check.Equals, int64(i)) + c.Logf("sink %d received event %d", si, logID) + c.Check(ev.LogID, check.Equals, int64(logID)) row := ev.Detail() - if i == 0 { - // no matching row, null event - c.Check(row, check.IsNil) - } else { - c.Check(row, check.NotNil) - c.Check(row.ID, check.Equals, int64(i)) + if c.Check(row, check.NotNil) { + c.Check(row.ID, check.Equals, int64(logID)) c.Check(row.UUID, check.Not(check.Equals), "") } } diff --git a/services/ws/event_test.go b/services/ws/event_test.go index 4665dfcd9e..f38bbbe5ad 100644 --- a/services/ws/event_test.go +++ b/services/ws/event_test.go @@ -21,5 +21,5 @@ func (*eventSuite) TestDetail(c *check.C) { c.Check(logRow.UUID, check.Equals, "zzzzz-57u5n-containerlog006") c.Check(logRow.ObjectUUID, check.Equals, "zzzzz-dz642-logscontainer03") c.Check(logRow.EventType, check.Equals, "crunchstat") - c.Check(logRow.Properties["text"], check.Equals, "2013-11-07_23:33:41 zzzzz-8i9sb-ahd7cie8jah9qui 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys") + c.Check(logRow.Properties["text"], check.Equals, "2013-11-07_23:33:41 zzzzz-dz642-logscontainer03 29610 1 stderr crunchstat: cpu 1935.4300 user 59.4100 sys 8 cpus -- interval 10.0002 seconds 12.9900 user 0.9900 sys") } diff --git a/tools/arvbox/lib/arvbox/docker/Dockerfile.base b/tools/arvbox/lib/arvbox/docker/Dockerfile.base index d8b2408831..927b975f8f 100644 --- a/tools/arvbox/lib/arvbox/docker/Dockerfile.base +++ b/tools/arvbox/lib/arvbox/docker/Dockerfile.base @@ -137,8 +137,7 @@ RUN echo arvados_version is git commit $arvados_version COPY $workdir/fuse.conf /etc/ -COPY $workdir/gitolite.rc \ - $workdir/keep-setup.sh $workdir/common.sh $workdir/createusers.sh \ +COPY $workdir/keep-setup.sh $workdir/common.sh $workdir/createusers.sh \ $workdir/logger $workdir/runsu.sh $workdir/waitforpostgres.sh \ $workdir/yml_override.py $workdir/api-setup.sh \ $workdir/go-setup.sh $workdir/devenv.sh $workdir/cluster-config.sh $workdir/edit_users.py \ diff --git a/tools/arvbox/lib/arvbox/docker/Dockerfile.demo b/tools/arvbox/lib/arvbox/docker/Dockerfile.demo index 81a5369f5e..dfbeaa448c 100644 --- a/tools/arvbox/lib/arvbox/docker/Dockerfile.demo +++ b/tools/arvbox/lib/arvbox/docker/Dockerfile.demo @@ -37,7 +37,6 @@ RUN sudo -u arvbox /var/lib/arvbox/service/keep-web/run-service --only-deps RUN sudo -u arvbox /var/lib/arvbox/service/doc/run-service --only-deps RUN sudo -u arvbox /var/lib/arvbox/service/vm/run-service --only-deps RUN sudo -u arvbox /var/lib/arvbox/service/keepproxy/run-service --only-deps -RUN sudo -u arvbox /var/lib/arvbox/service/arv-git-httpd/run-service --only-deps RUN sudo -u arvbox /var/lib/arvbox/service/websockets/run --only-deps RUN sudo -u arvbox /usr/local/lib/arvbox/keep-setup.sh --only-deps RUN sudo -u arvbox /var/lib/arvbox/service/sdk/run-service diff --git a/tools/arvbox/lib/arvbox/docker/api-setup.sh b/tools/arvbox/lib/arvbox/docker/api-setup.sh index 29cea1ecbe..b2d20a455c 100755 --- a/tools/arvbox/lib/arvbox/docker/api-setup.sh +++ b/tools/arvbox/lib/arvbox/docker/api-setup.sh @@ -38,8 +38,6 @@ $RAILS_ENV: blob_signing_key: $blob_signing_key workbench_address: "https://$localip/" websocket_address: "wss://$localip:${services[websockets-ssl]}/websocket" - git_repo_ssh_base: "git@$localip:" - git_repo_https_base: "http://$localip:${services[arv-git-httpd]}/" new_users_are_active: true auto_admin_first_user: true auto_setup_new_users: true diff --git a/tools/arvbox/lib/arvbox/docker/cluster-config.sh b/tools/arvbox/lib/arvbox/docker/cluster-config.sh index 9b55181c91..d07fc3d34d 100755 --- a/tools/arvbox/lib/arvbox/docker/cluster-config.sh +++ b/tools/arvbox/lib/arvbox/docker/cluster-config.sh @@ -87,12 +87,6 @@ Clusters: ExternalURL: "wss://$localip:${services[websockets-ssl]}/websocket" InternalURLs: "http://localhost:${services[websockets]}": {} - GitSSH: - ExternalURL: "ssh://git@$localip:" - GitHTTP: - InternalURLs: - "http://localhost:${services[arv-git-httpd]}/": {} - ExternalURL: "https://$localip:${services[arv-git-httpd-ssl]}/" WebDAV: InternalURLs: "http://localhost:${services[keep-web]}/": {} @@ -132,11 +126,6 @@ Clusters: AutoAdminFirstUser: true AutoSetupNewUsers: true AutoSetupNewUsersWithVmUUID: $vm_uuid - AutoSetupNewUsersWithRepository: true - Git: - GitCommand: /usr/share/gitolite3/gitolite-shell - GitoliteHome: $ARVADOS_CONTAINER_PATH/git - Repositories: $ARVADOS_CONTAINER_PATH/git/repositories Volumes: ${uuid_prefix}-nyw5e-000000000000000: Driver: Directory diff --git a/tools/arvbox/lib/arvbox/docker/common.sh b/tools/arvbox/lib/arvbox/docker/common.sh index 54ec9403ad..2232b63c4f 100644 --- a/tools/arvbox/lib/arvbox/docker/common.sh +++ b/tools/arvbox/lib/arvbox/docker/common.sh @@ -2,9 +2,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -export RUBY_VERSION=3.2.2 -export BUNDLER_VERSION=2.4.22 - export DEBIAN_FRONTEND=noninteractive export PATH=${PATH}:/usr/local/go/bin:/var/lib/arvados/bin:/opt/arvados-py/bin:/usr/src/arvados/sdk/cli/binstubs export npm_config_cache=/var/lib/npm @@ -40,8 +37,6 @@ services=( [api]=8004 [controller]=8003 [controller-ssl]=8000 - [arv-git-httpd-ssl]=9000 - [arv-git-httpd]=9001 [keep-web]=9003 [keep-web-ssl]=9002 [keep-web-dl-ssl]=9004 @@ -66,7 +61,7 @@ else fi run_bundler() { - flock $GEMLOCK /var/lib/arvados/bin/gem install --no-document --user bundler:$BUNDLER_VERSION + flock $GEMLOCK /var/lib/arvados/bin/gem install --conservative --no-document --user --version '~> 2.4.0' bundler BUNDLER=bundle if test -x $PWD/bin/bundle ; then diff --git a/tools/arvbox/lib/arvbox/docker/gitolite.rc b/tools/arvbox/lib/arvbox/docker/gitolite.rc deleted file mode 100644 index 07a9ce0d44..0000000000 --- a/tools/arvbox/lib/arvbox/docker/gitolite.rc +++ /dev/null @@ -1,217 +0,0 @@ -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -# This is based on the default Gitolite configuration file with the following -# changes applied as described here: -# http://doc.arvados.org/install/install-arv-git-httpd.html - -# configuration variables for gitolite - -# This file is in perl syntax. But you do NOT need to know perl to edit it -- -# just mind the commas, use single quotes unless you know what you're doing, -# and make sure the brackets and braces stay matched up! - -# (Tip: perl allows a comma after the last item in a list also!) - -# HELP for commands can be had by running the command with "-h". - -# HELP for all the other FEATURES can be found in the documentation (look for -# "list of non-core programs shipped with gitolite" in the master index) or -# directly in the corresponding source file. - -my $repo_aliases; -my $aliases_src = "$ENV{HOME}/.gitolite/arvadosaliases.pl"; -if ($ENV{HOME} && (-e $aliases_src)) { - $repo_aliases = do $aliases_src; -} -$repo_aliases ||= {}; - -%RC = ( - - REPO_ALIASES => $repo_aliases, - - # ------------------------------------------------------------------ - - # default umask gives you perms of '0700'; see the rc file docs for - # how/why you might change this - UMASK => 0022, - - # look for "git-config" in the documentation - GIT_CONFIG_KEYS => '', - - # comment out if you don't need all the extra detail in the logfile - LOG_EXTRA => 1, - # logging options - # 1. leave this section as is for 'normal' gitolite logging (default) - # 2. uncomment this line to log ONLY to syslog: - # LOG_DEST => 'syslog', - # 3. uncomment this line to log to syslog and the normal gitolite log: - # LOG_DEST => 'syslog,normal', - # 4. prefixing "repo-log," to any of the above will **also** log just the - # update records to "gl-log" in the bare repo directory: - # LOG_DEST => 'repo-log,normal', - # LOG_DEST => 'repo-log,syslog', - # LOG_DEST => 'repo-log,syslog,normal', - - # roles. add more roles (like MANAGER, TESTER, ...) here. - # WARNING: if you make changes to this hash, you MUST run 'gitolite - # compile' afterward, and possibly also 'gitolite trigger POST_COMPILE' - ROLES => { - READERS => 1, - WRITERS => 1, - }, - - # enable caching (currently only Redis). PLEASE RTFM BEFORE USING!!! - # CACHE => 'Redis', - - # ------------------------------------------------------------------ - - # rc variables used by various features - - # the 'info' command prints this as additional info, if it is set - # SITE_INFO => 'Please see http://blahblah/gitolite for more help', - - # the CpuTime feature uses these - # display user, system, and elapsed times to user after each git operation - # DISPLAY_CPU_TIME => 1, - # display a warning if total CPU times (u, s, cu, cs) crosses this limit - # CPU_TIME_WARN_LIMIT => 0.1, - - # the Mirroring feature needs this - # HOSTNAME => "foo", - - # TTL for redis cache; PLEASE SEE DOCUMENTATION BEFORE UNCOMMENTING! - # CACHE_TTL => 600, - - # ------------------------------------------------------------------ - - # suggested locations for site-local gitolite code (see cust.html) - - # this one is managed directly on the server - # LOCAL_CODE => "$ENV{HOME}/local", - - # or you can use this, which lets you put everything in a subdirectory - # called "local" in your gitolite-admin repo. For a SECURITY WARNING - # on this, see http://gitolite.com/gitolite/non-core.html#pushcode - # LOCAL_CODE => "$rc{GL_ADMIN_BASE}/local", - - # ------------------------------------------------------------------ - - # List of commands and features to enable - - ENABLE => [ - - # COMMANDS - - # These are the commands enabled by default - 'help', - 'desc', - 'info', - 'perms', - 'writable', - - # Uncomment or add new commands here. - # 'create', - # 'fork', - # 'mirror', - # 'readme', - # 'sskm', - # 'D', - - # These FEATURES are enabled by default. - - # essential (unless you're using smart-http mode) - 'ssh-authkeys', - - # creates git-config enties from gitolite.conf file entries like 'config foo.bar = baz' - 'git-config', - - # creates git-daemon-export-ok files; if you don't use git-daemon, comment this out - 'daemon', - - # creates projects.list file; if you don't use gitweb, comment this out - 'gitweb', - - # These FEATURES are disabled by default; uncomment to enable. If you - # need to add new ones, ask on the mailing list :-) - - # user-visible behaviour - - # prevent wild repos auto-create on fetch/clone - # 'no-create-on-read', - # no auto-create at all (don't forget to enable the 'create' command!) - # 'no-auto-create', - - # access a repo by another (possibly legacy) name - 'Alias', - - # give some users direct shell access. See documentation in - # sts.html for details on the following two choices. - # "Shell $ENV{HOME}/.gitolite.shell-users", - # 'Shell alice bob', - - # set default roles from lines like 'option default.roles-1 = ...', etc. - # 'set-default-roles', - - # show more detailed messages on deny - # 'expand-deny-messages', - - # show a message of the day - # 'Motd', - - # system admin stuff - - # enable mirroring (don't forget to set the HOSTNAME too!) - # 'Mirroring', - - # allow people to submit pub files with more than one key in them - # 'ssh-authkeys-split', - - # selective read control hack - # 'partial-copy', - - # manage local, gitolite-controlled, copies of read-only upstream repos - # 'upstream', - - # updates 'description' file instead of 'gitweb.description' config item - # 'cgit', - - # allow repo-specific hooks to be added - # 'repo-specific-hooks', - - # performance, logging, monitoring... - - # be nice - # 'renice 10', - - # log CPU times (user, system, cumulative user, cumulative system) - # 'CpuTime', - - # syntactic_sugar for gitolite.conf and included files - - # allow backslash-escaped continuation lines in gitolite.conf - # 'continuation-lines', - - # create implicit user groups from directory names in keydir/ - # 'keysubdirs-as-groups', - - # allow simple line-oriented macros - # 'macros', - - # Kindergarten mode - - # disallow various things that sensible people shouldn't be doing anyway - # 'Kindergarten', - ], - -); - -# ------------------------------------------------------------------------------ -# per perl rules, this should be the last line in such a file: -1; - -# Local variables: -# mode: perl -# End: -# vim: set syn=perl: diff --git a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/log/main/.gitstub b/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/log/main/.gitstub deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/log/run b/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/log/run deleted file mode 120000 index d6aef4a77d..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/log/run +++ /dev/null @@ -1 +0,0 @@ -/usr/local/lib/arvbox/logger \ No newline at end of file diff --git a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run b/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run deleted file mode 120000 index a388c8b67b..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run +++ /dev/null @@ -1 +0,0 @@ -/usr/local/lib/arvbox/runsu.sh \ No newline at end of file diff --git a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run-service b/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run-service deleted file mode 100755 index b598a75d89..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/arv-git-httpd/run-service +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -exec 2>&1 -set -ex -o pipefail - -. /usr/local/lib/arvbox/common.sh -. /usr/local/lib/arvbox/go-setup.sh - -(cd /usr/local/bin && ln -sf arvados-server arvados-git-httpd) - -if test "$1" = "--only-deps" ; then - exit -fi - -flock $ARVADOS_CONTAINER_PATH/cluster_config.yml.lock /usr/local/lib/arvbox/cluster-config.sh - -export PATH="$PATH:$ARVADOS_CONTAINER_PATH/git/bin" -cd ~git -exec /usr/local/bin/arvados-git-httpd diff --git a/tools/arvbox/lib/arvbox/docker/service/gitolite/log/main/.gitstub b/tools/arvbox/lib/arvbox/docker/service/gitolite/log/main/.gitstub deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tools/arvbox/lib/arvbox/docker/service/gitolite/log/run b/tools/arvbox/lib/arvbox/docker/service/gitolite/log/run deleted file mode 120000 index d6aef4a77d..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/gitolite/log/run +++ /dev/null @@ -1 +0,0 @@ -/usr/local/lib/arvbox/logger \ No newline at end of file diff --git a/tools/arvbox/lib/arvbox/docker/service/gitolite/run b/tools/arvbox/lib/arvbox/docker/service/gitolite/run deleted file mode 120000 index a388c8b67b..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/gitolite/run +++ /dev/null @@ -1 +0,0 @@ -/usr/local/lib/arvbox/runsu.sh \ No newline at end of file diff --git a/tools/arvbox/lib/arvbox/docker/service/gitolite/run-service b/tools/arvbox/lib/arvbox/docker/service/gitolite/run-service deleted file mode 100755 index 5f2cbc8825..0000000000 --- a/tools/arvbox/lib/arvbox/docker/service/gitolite/run-service +++ /dev/null @@ -1,130 +0,0 @@ -#!/bin/bash -# Copyright (C) The Arvados Authors. All rights reserved. -# -# SPDX-License-Identifier: AGPL-3.0 - -exec 2>&1 -set -eux -o pipefail - -. /usr/local/lib/arvbox/common.sh - -if test "$1" != "--only-deps" ; then - while [ ! -f $ARVADOS_CONTAINER_PATH/api.ready ]; do - sleep 1 - done -fi - -mkdir -p $ARVADOS_CONTAINER_PATH/git - -export ARVADOS_API_HOST=$localip:${services[controller-ssl]} -export ARVADOS_API_HOST_INSECURE=1 -export ARVADOS_API_TOKEN=$(cat $ARVADOS_CONTAINER_PATH/superuser_token) - -export USER=git -export USERNAME=git -export LOGNAME=git -export HOME=$ARVADOS_CONTAINER_PATH/git - -cd ~arvbox - -mkdir -p ~arvbox/.ssh ~git/.ssh -chmod 0700 ~arvbox/.ssh ~git/.ssh - -if ! test -s ~arvbox/.ssh/id_rsa ; then - ssh-keygen -t rsa -P '' -f .ssh/id_rsa - cp ~arvbox/.ssh/id_rsa ~arvbox/.ssh/id_rsa.pub ~git/.ssh -fi - -if test -s ~arvbox/.ssh/known_hosts ; then - ssh-keygen -f ".ssh/known_hosts" -R localhost -fi - -if ! test -f $ARVADOS_CONTAINER_PATH/gitolite-setup ; then - cd ~git - - # Do a no-op login to populate known_hosts - # with the hostkey, so it won't try to ask - # about it later. - cp .ssh/id_rsa.pub .ssh/authorized_keys - ssh -o stricthostkeychecking=no git@localhost true - rm .ssh/authorized_keys - - cp /usr/local/lib/arvbox/gitolite.rc .gitolite.rc - - gitolite setup -pk .ssh/id_rsa.pub - - if ! test -d gitolite-admin ; then - git clone git@localhost:gitolite-admin - fi - - cd gitolite-admin - git config user.email arvados - git config user.name arvados - git config push.default simple - git push - - touch $ARVADOS_CONTAINER_PATH/gitolite-setup -else - # Do a no-op login to populate known_hosts - # with the hostkey, so it won't try to ask - # about it later. Don't run anything, - # get the default gitolite behavior. - ssh -o stricthostkeychecking=no git@localhost -fi - -prefix=$(arv --format=uuid user current | cut -d- -f1) - -if ! test -s $ARVADOS_CONTAINER_PATH/arvados-git-uuid ; then - repo_uuid=$(arv --format=uuid repository create --repository "{\"owner_uuid\":\"$prefix-tpzed-000000000000000\", \"name\":\"arvados\"}") - echo $repo_uuid > $ARVADOS_CONTAINER_PATH/arvados-git-uuid -fi - -repo_uuid=$(cat $ARVADOS_CONTAINER_PATH/arvados-git-uuid) - -if ! test -s $ARVADOS_CONTAINER_PATH/arvados-git-link-uuid ; then - all_users_group_uuid="$prefix-j7d0g-fffffffffffffff" - - set +e - read -rd $'\000' newlink < $ARVADOS_CONTAINER_PATH/arvados-git-link-uuid -fi - -if ! test -d $ARVADOS_CONTAINER_PATH/git/repositories/$repo_uuid.git ; then - git clone --bare /usr/src/arvados $ARVADOS_CONTAINER_PATH/git/repositories/$repo_uuid.git -else - git --git-dir=$ARVADOS_CONTAINER_PATH/git/repositories/$repo_uuid.git fetch -f /usr/src/arvados main:main -fi - -cd /usr/src/arvados/services/api - -if test -s $ARVADOS_CONTAINER_PATH/api_rails_env ; then - RAILS_ENV=$(cat $ARVADOS_CONTAINER_PATH/api_rails_env) -else - RAILS_ENV=development -fi - -git_user_key=$(cat ~git/.ssh/id_rsa.pub) - -cat > config/arvados-clients.yml </dev/null; if [ "$1" = get ]; then echo password=$ARVADOS_API_TOKEN; fi; };cred' - /usr/local/lib/arvbox/runsu.sh $0-service cd /usr/src/arvados/services/login-sync diff --git a/tools/compute-images/scripts/base.sh b/tools/compute-images/scripts/base.sh index 370c3f3a3a..c19febdc01 100644 --- a/tools/compute-images/scripts/base.sh +++ b/tools/compute-images/scripts/base.sh @@ -15,8 +15,8 @@ wait_for_apt_locks() { done } -# $DIST should not have a dot if there is one in /etc/os-release (e.g. 18.04) -DIST=$(. /etc/os-release; echo $ID$VERSION_ID | tr -d '.') +. /etc/os-release +DISTRO_ID="$ID" # Run apt-get update $SUDO DEBIAN_FRONTEND=noninteractive apt-get --yes update @@ -36,9 +36,6 @@ if [[ ! -d /var/lib/cloud/scripts/per-boot ]]; then mkdir -p /var/lib/cloud/scripts/per-boot fi -TMP_LSB=`/usr/bin/lsb_release -c -s` -LSB_RELEASE_CODENAME=${TMP_LSB//[$'\t\r\n ']} - SET_RESOLVER= if [ -n "$RESOLVER" ]; then SET_RESOLVER="--dns ${RESOLVER}" @@ -46,7 +43,7 @@ fi # Add the arvados apt repository echo "# apt.arvados.org" |$SUDO tee --append /etc/apt/sources.list.d/apt.arvados.org.list -echo "deb http://apt.arvados.org/$LSB_RELEASE_CODENAME $LSB_RELEASE_CODENAME${REPOSUFFIX} main" |$SUDO tee --append /etc/apt/sources.list.d/apt.arvados.org.list +echo "deb http://apt.arvados.org/$VERSION_CODENAME $VERSION_CODENAME${REPOSUFFIX} main" |$SUDO tee --append /etc/apt/sources.list.d/apt.arvados.org.list # Add the arvados signing key cat /tmp/1078ECD7.asc | $SUDO apt-key add - @@ -75,32 +72,12 @@ wait_for_apt_locks && $SUDO DEBIAN_FRONTEND=noninteractive apt-get -qq --yes ins python3-arvados-fuse \ arvados-docker-cleaner -# We want Docker 20.10 or later so that we support glibc 2.33 and up in the container, cf. -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1005906 -dockerversion=5:20.10.13~3-0 -if [[ "$DIST" =~ ^debian ]]; then - family="debian" - if [ "$DIST" == "debian11" ]; then - distro="bullseye" - elif [ "$DIST" == "debian12" ]; then - distro="bookworm" - fi -elif [[ "$DIST" =~ ^ubuntu ]]; then - family="ubuntu" - if [ "$DIST" == "ubuntu2004" ]; then - distro="focal" - elif [ "$DIST" == "ubuntu2204" ]; then - distro="jammy" - fi -else - echo "Unsupported distribution $DIST" - exit 1 -fi -curl -fsSL https://download.docker.com/linux/$family/gpg | $SUDO gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg -echo deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/$family/ $distro stable | \ +DOCKER_URL="https://download.docker.com/linux/$DISTRO_ID" +curl -fsSL "$DOCKER_URL/gpg" | $SUDO gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg +echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] $DOCKER_URL/ $VERSION_CODENAME stable" | \ $SUDO tee /etc/apt/sources.list.d/docker.list $SUDO apt-get update -$SUDO apt-get -yq --no-install-recommends install docker-ce=${dockerversion}~${family}-${distro} +$SUDO apt-get -yq --no-install-recommends install docker-ce # Set a higher ulimit and the resolver (if set) for docker $SUDO sed "s/ExecStart=\(.*\)/ExecStart=\1 --default-ulimit nofile=10000:10000 ${SET_RESOLVER}/g" \ @@ -173,7 +150,7 @@ $SUDO chown root:root /etc/cloud/cloud.cfg.d/07_compute_arvados_dispatch_cloud.c if [ "$NVIDIA_GPU_SUPPORT" == "1" ]; then # We need a kernel and matching headers - if [[ "$DIST" =~ ^debian ]]; then + if [[ "$DISTRO_ID" == debian ]]; then $SUDO apt-get -y install linux-image-cloud-amd64 linux-headers-cloud-amd64 elif [ "$CLOUD" == "azure" ]; then $SUDO apt-get -y install linux-image-azure linux-headers-azure @@ -182,10 +159,11 @@ if [ "$NVIDIA_GPU_SUPPORT" == "1" ]; then fi # Install CUDA - $SUDO apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/$DIST/x86_64/7fa2af80.pub - $SUDO apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/$DIST/x86_64/3bf863cc.pub + NVIDIA_URL="https://developer.download.nvidia.com/compute/cuda/repos/$(echo "$DISTRO_ID$VERSION_ID" | tr -d .)/x86_64" + $SUDO apt-key adv --fetch-keys "$NVIDIA_URL/7fa2af80.pub" + $SUDO apt-key adv --fetch-keys "$NVIDIA_URL/3bf863cc.pub" $SUDO apt-get -y install software-properties-common - $SUDO add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/$DIST/x86_64/ /" + $SUDO add-apt-repository "deb $NVIDIA_URL/ /" $SUDO add-apt-repository contrib $SUDO apt-get update $SUDO apt-get -y install cuda @@ -193,7 +171,7 @@ if [ "$NVIDIA_GPU_SUPPORT" == "1" ]; then # Install libnvidia-container, the tooling for Docker/Singularity curl -s -L https://nvidia.github.io/libnvidia-container/gpgkey | \ $SUDO apt-key add - - if [ "$DIST" == "debian11" ]; then + if [[ "$VERSION_CODENAME" == bullseye ]]; then # As of 2021-12-16 libnvidia-container and friends are only available for # Debian 10, not yet Debian 11. Install experimental rc1 package as per this # workaround: @@ -202,9 +180,7 @@ if [ "$NVIDIA_GPU_SUPPORT" == "1" ]; then $SUDO tee /etc/apt/sources.list.d/libnvidia-container.list $SUDO sed -i -e '/experimental/ s/^#//g' /etc/apt/sources.list.d/libnvidia-container.list else - # here, $DIST should have a dot if there is one in /etc/os-release (e.g. 18.04)... - DIST=$(. /etc/os-release; echo $ID$VERSION_ID) - curl -s -L https://nvidia.github.io/libnvidia-container/$DIST/libnvidia-container.list | \ + curl -s -L "https://nvidia.github.io/libnvidia-container/$DISTRO_ID$VERSION_ID/libnvidia-container.list" | \ $SUDO tee /etc/apt/sources.list.d/libnvidia-container.list fi diff --git a/tools/crunchstat-summary/arvados_version.py b/tools/crunchstat-summary/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/tools/crunchstat-summary/arvados_version.py +++ b/tools/crunchstat-summary/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/tools/crunchstat-summary/bin/crunchstat-summary b/tools/crunchstat-summary/bin/crunchstat-summary index 3c18829189..bfd85ec9e1 100755 --- a/tools/crunchstat-summary/bin/crunchstat-summary +++ b/tools/crunchstat-summary/bin/crunchstat-summary @@ -3,8 +3,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import print_function - import crunchstat_summary.command import crunchstat_summary.summarizer import logging diff --git a/tools/crunchstat-summary/pytest.ini b/tools/crunchstat-summary/pytest.ini new file mode 120000 index 0000000000..05a82dbfef --- /dev/null +++ b/tools/crunchstat-summary/pytest.ini @@ -0,0 +1 @@ +../../sdk/python/pytest.ini \ No newline at end of file diff --git a/tools/crunchstat-summary/setup.py b/tools/crunchstat-summary/setup.py index 24a6bf5e4f..d5adc92367 100755 --- a/tools/crunchstat-summary/setup.py +++ b/tools/crunchstat-summary/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import os import sys import re @@ -12,7 +11,6 @@ from setuptools import setup, find_packages import arvados_version version = arvados_version.get_version() -short_tests_only = arvados_version.short_tests_only() README = os.path.join(arvados_version.SETUP_DIR, 'README.rst') setup(name='crunchstat_summary', @@ -36,6 +34,5 @@ setup(name='crunchstat_summary', ], python_requires="~=3.8", test_suite='tests', - tests_require=['pbr<1.7.0', 'mock>=1.0'], zip_safe=False, ) diff --git a/tools/crunchstat-summary/tests/test_examples.py b/tools/crunchstat-summary/tests/test_examples.py index 5a20d3283f..7d97fd3edc 100644 --- a/tools/crunchstat-summary/tests/test_examples.py +++ b/tools/crunchstat-summary/tests/test_examples.py @@ -10,11 +10,12 @@ import glob import gzip import io import logging -import mock import os import sys import unittest +from unittest import mock + from crunchstat_summary.command import UTF8Decode from crunchstat_summary import logger, reader diff --git a/tools/keep-xref/keep-xref.py b/tools/keep-xref/keep-xref.py index d77e593640..77e8bc5d91 100755 --- a/tools/keep-xref/keep-xref.py +++ b/tools/keep-xref/keep-xref.py @@ -5,7 +5,6 @@ # SPDX-License-Identifier: AGPL-3.0 # -from __future__ import print_function, absolute_import import argparse import arvados import arvados.util diff --git a/tools/salt-install/config_examples/multi_host/aws/pillars/arvados.sls b/tools/salt-install/config_examples/multi_host/aws/pillars/arvados.sls index 16e686ab80..ce95a256b0 100644 --- a/tools/salt-install/config_examples/multi_host/aws/pillars/arvados.sls +++ b/tools/salt-install/config_examples/multi_host/aws/pillars/arvados.sls @@ -166,7 +166,6 @@ arvados: NewUsersAreActive: true AutoAdminFirstUser: true AutoSetupNewUsers: true - AutoSetupNewUsersWithRepository: true Services: Controller: diff --git a/tools/salt-install/config_examples/multi_host/aws/pillars/logrotate.sls b/tools/salt-install/config_examples/multi_host/aws/pillars/logrotate.sls new file mode 100644 index 0000000000..8c455e9c78 --- /dev/null +++ b/tools/salt-install/config_examples/multi_host/aws/pillars/logrotate.sls @@ -0,0 +1,14 @@ +--- +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +# The logrotate formula checks that an associated service is running. +# The default it checks is cron. +# All the distributions Arvados supports (Debian 11+/Ubuntu 20.04+) +# have switched to a systemd timer, so check that instead. +# Refer to logrotate-formula's documentation for details +# https://github.com/salt-formulas/salt-formula-logrotate/blob/master/README.rst + +logrotate: + service: logrotate.timer diff --git a/tools/salt-install/config_examples/multi_host/aws/pillars/nginx_api_configuration.sls b/tools/salt-install/config_examples/multi_host/aws/pillars/nginx_api_configuration.sls index bfe0386e93..d27552f6fb 100644 --- a/tools/salt-install/config_examples/multi_host/aws/pillars/nginx_api_configuration.sls +++ b/tools/salt-install/config_examples/multi_host/aws/pillars/nginx_api_configuration.sls @@ -25,4 +25,5 @@ nginx: - access_log: /var/log/nginx/api.__DOMAIN__-upstream.access.log combined - error_log: /var/log/nginx/api.__DOMAIN__-upstream.error.log - passenger_enabled: 'on' + - passenger_preload_bundler: 'on' - client_max_body_size: 128m diff --git a/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/arvados.sls b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/arvados.sls index 271ab50290..a2bfdb19b0 100644 --- a/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/arvados.sls +++ b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/arvados.sls @@ -128,7 +128,6 @@ arvados: NewUsersAreActive: true AutoAdminFirstUser: true AutoSetupNewUsers: true - AutoSetupNewUsersWithRepository: true Services: Controller: diff --git a/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/logrotate.sls b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/logrotate.sls new file mode 100644 index 0000000000..8c455e9c78 --- /dev/null +++ b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/logrotate.sls @@ -0,0 +1,14 @@ +--- +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +# The logrotate formula checks that an associated service is running. +# The default it checks is cron. +# All the distributions Arvados supports (Debian 11+/Ubuntu 20.04+) +# have switched to a systemd timer, so check that instead. +# Refer to logrotate-formula's documentation for details +# https://github.com/salt-formulas/salt-formula-logrotate/blob/master/README.rst + +logrotate: + service: logrotate.timer diff --git a/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/nginx_api_configuration.sls b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/nginx_api_configuration.sls index 54087f6d6d..b567af90d7 100644 --- a/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/nginx_api_configuration.sls +++ b/tools/salt-install/config_examples/single_host/multiple_hostnames/pillars/nginx_api_configuration.sls @@ -31,4 +31,5 @@ nginx: - access_log: /var/log/nginx/api.__CLUSTER__.__DOMAIN__-upstream.access.log combined - error_log: /var/log/nginx/api.__CLUSTER__.__DOMAIN__-upstream.error.log - passenger_enabled: 'on' + - passenger_preload_bundler: 'on' - client_max_body_size: 128m diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls index 9e3a293110..03db62ab5d 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/arvados.sls @@ -131,7 +131,6 @@ arvados: NewUsersAreActive: true AutoAdminFirstUser: true AutoSetupNewUsers: true - AutoSetupNewUsersWithRepository: true Services: Controller: diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/logrotate.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/logrotate.sls new file mode 100644 index 0000000000..8c455e9c78 --- /dev/null +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/logrotate.sls @@ -0,0 +1,14 @@ +--- +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: AGPL-3.0 + +# The logrotate formula checks that an associated service is running. +# The default it checks is cron. +# All the distributions Arvados supports (Debian 11+/Ubuntu 20.04+) +# have switched to a systemd timer, so check that instead. +# Refer to logrotate-formula's documentation for details +# https://github.com/salt-formulas/salt-formula-logrotate/blob/master/README.rst + +logrotate: + service: logrotate.timer diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls index 04195ae5b9..3bf7bf54ab 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_api_configuration.sls @@ -31,4 +31,5 @@ nginx: - access_log: /var/log/nginx/api.__CLUSTER__.__DOMAIN__-upstream.access.log combined - error_log: /var/log/nginx/api.__CLUSTER__.__DOMAIN__-upstream.error.log - passenger_enabled: 'on' + - passenger_preload_bundler: 'on' - client_max_body_size: 128m diff --git a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls index 59fb43e57a..5d5d0af668 100644 --- a/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls +++ b/tools/salt-install/config_examples/single_host/single_hostname/pillars/nginx_workbench_configuration.sls @@ -78,6 +78,7 @@ nginx: - root: /var/www/arvados-workbench/current/public - index: index.html index.htm - passenger_enabled: 'on' + - passenger_preload_bundler: 'on' # yamllint disable-line rule:line-length - access_log: /var/log/nginx/workbench.__CLUSTER__.__DOMAIN__-upstream.access.log combined - error_log: /var/log/nginx/workbench.__CLUSTER__.__DOMAIN__-upstream.error.log diff --git a/tools/salt-install/installer.sh b/tools/salt-install/installer.sh index 439293c296..36e87cca91 100755 --- a/tools/salt-install/installer.sh +++ b/tools/salt-install/installer.sh @@ -449,14 +449,38 @@ diagnostics) arvados-client diagnostics $LOCATION ;; +diagnostics-internal) + loadconfig + set -u + + if [ -z "${ROLE2NODES['shell']:-}" ]; then + echo "No node with 'shell' role was found, cannot run diagnostics-internal" + exit 1 + fi + + # Pick the first shell node for test running + declare TESTNODE=$(echo ${ROLE2NODES['shell']} | cut -d\, -f1) + declare SSH=$(ssh_cmd "$TESTNODE") + + # Run diagnostics + echo "Running diagnostics in $TESTNODE..." + $SSH $DEPLOY_USER@$TESTNODE bash <&2 "${0} options:" echo >&2 " -d, --debug Run salt installation in debug mode" echo >&2 " -c , --config Path to the local.params config file" - echo >&2 " -t, --test Test installation running a CWL workflow" + echo >&2 " -t, --test Test cluster by running \`arvados-client diagnostics\`" + echo >&2 " and a simple workflow" echo >&2 " -r, --roles List of Arvados roles to apply to the host, comma separated" echo >&2 " Possible values are:" echo >&2 " balancer" @@ -284,17 +285,15 @@ VERSION="latest" # We pin the salt version to avoid potential incompatibilities when a new # stable version is released. -SALT_VERSION="3004" +SALT_VERSION="3006" # Other formula versions we depend on -#POSTGRES_TAG="v0.44.0" -#POSTGRES_URL="https://github.com/saltstack-formulas/postgres-formula.git" -POSTGRES_TAG="0.45.0-bugfix327" -POSTGRES_URL="https://github.com/arvados/postgres-formula.git" +POSTGRES_TAG="7529300c287b1c288af0f494ca668c2217bd1c5d" +POSTGRES_URL="https://github.com/saltstack-formulas/postgres-formula.git" NGINX_TAG="v2.8.1" DOCKER_TAG="v2.4.2" -LOCALE_TAG="v0.3.4" -LETSENCRYPT_TAG="v2.1.0" +LOCALE_TAG="v0.3.5" +LETSENCRYPT_TAG="v3.2.0" LOGROTATE_TAG="v0.14.0" PROMETHEUS_TAG="v5.6.5" GRAFANA_TAG="v3.1.3" @@ -362,23 +361,24 @@ fi if [ "${DUMP_CONFIG}" = "yes" ]; then echo "The provision installer will just dump a config under ${DUMP_SALT_CONFIG_DIR} and exit" else - # Install a few dependency packages - # First, let's figure out the OS we're working on OS_IDS="$(. /etc/os-release && echo "${ID:-} ${ID_LIKE:-}")" echo "Detected distro families: $OS_IDS" + # Several of our formulas use the cron module, which requires the crontab + # command. We install systemd-cron to ensure we have that. + # The rest of these packages are required by the rest of the script. for OS_ID in $OS_IDS; do case "$OS_ID" in rhel) echo "WARNING! Disabling SELinux, see https://dev.arvados.org/issues/18019" sed -i 's/SELINUX=enforcing/SELINUX=permissive/g' /etc/sysconfig/selinux setenforce permissive - yum install -y curl git jq + yum install -y curl git jq systemd-cron break ;; debian) DEBIAN_FRONTEND=noninteractive apt -o DPkg::Lock::Timeout=120 update - DEBIAN_FRONTEND=noninteractive apt install -y curl git jq + DEBIAN_FRONTEND=noninteractive apt install -y curl git jq systemd-cron break ;; esac @@ -388,7 +388,7 @@ else echo "Salt already installed" else curl -L https://bootstrap.saltstack.com -o /tmp/bootstrap_salt.sh - sh /tmp/bootstrap_salt.sh -XdfP -x python3 old-stable ${SALT_VERSION} + sh /tmp/bootstrap_salt.sh -XdfP -x python3 stable ${SALT_VERSION} /bin/systemctl stop salt-minion.service /bin/systemctl disable salt-minion.service fi @@ -431,7 +431,7 @@ test -d nginx && ( cd nginx && git fetch ) \ echo "...postgres" test -d postgres && ( cd postgres && git fetch ) \ || git clone --quiet ${POSTGRES_URL} ${F_DIR}/postgres -( cd postgres && git checkout --quiet tags/"${POSTGRES_TAG}" ) +( cd postgres && git checkout --quiet "${POSTGRES_TAG}" ) echo "...prometheus" test -d prometheus && ( cd prometheus && git fetch ) \ @@ -620,6 +620,7 @@ if [ -z "${ROLES:-}" ]; then # Pillars echo " - docker" >> ${PILLARS_TOP} echo " - nginx_api_configuration" >> ${PILLARS_TOP} + echo " - logrotate" >> ${PILLARS_TOP} echo " - logrotate_api" >> ${PILLARS_TOP} echo " - nginx_controller_configuration" >> ${PILLARS_TOP} echo " - nginx_keepproxy_configuration" >> ${PILLARS_TOP} @@ -855,6 +856,7 @@ else grep -q "arvados.controller" ${STATES_TOP} || echo " - arvados.controller" >> ${STATES_TOP} ### Pillars ### + grep -q "logrotate" ${PILLARS_TOP} || echo " - logrotate" >> ${PILLARS_TOP} grep -q "logrotate_api" ${PILLARS_TOP} || echo " - logrotate_api" >> ${PILLARS_TOP} grep -q "aws_credentials" ${PILLARS_TOP} || echo " - aws_credentials" >> ${PILLARS_TOP} grep -q "postgresql" ${PILLARS_TOP} || echo " - postgresql" >> ${PILLARS_TOP} diff --git a/tools/salt-install/terraform/aws/services/main.tf b/tools/salt-install/terraform/aws/services/main.tf index 54e2fc412b..06564edad6 100644 --- a/tools/salt-install/terraform/aws/services/main.tf +++ b/tools/salt-install/terraform/aws/services/main.tf @@ -70,6 +70,7 @@ resource "aws_instance" "arvados_service" { metadata_options { # Sets IMDSv2 to required. Default is "optional". http_tokens = "required" + http_endpoint = "enabled" } lifecycle { ignore_changes = [ diff --git a/tools/salt-install/tests/run-test.sh b/tools/salt-install/tests/run-test.sh index cf43273a14..f56b252766 100755 --- a/tools/salt-install/tests/run-test.sh +++ b/tools/salt-install/tests/run-test.sh @@ -17,6 +17,13 @@ if ! curl -s -o /dev/null https://${ARVADOS_API_HOST}/users/welcome?return_to=%2 exit 1 fi +# Then, run a basic diagnostics test. +echo "Running arvados-client diagnostics..." +if ! arvados-client diagnostics -internal-client; then + echo "Diagnostics run FAILED, exiting" + exit 1 +fi + # https://doc.arvados.org/v2.0/install/install-jobs-image.html echo "Creating Arvados Standard Docker Images project" uuid_prefix=$(arv --format=uuid user current | cut -d- -f1) diff --git a/tools/user-activity/arvados_version.py b/tools/user-activity/arvados_version.py index 794b6afe42..ca20de4c58 100644 --- a/tools/user-activity/arvados_version.py +++ b/tools/user-activity/arvados_version.py @@ -72,14 +72,6 @@ if REPO_PATH is None: if (SETUP_DIR / mod_name).is_dir() ) -def short_tests_only(arglist=sys.argv): - try: - arglist.remove('--short-tests-only') - except ValueError: - return False - else: - return True - def git_log_output(path, *args): return subprocess.check_output( ['git', '-C', str(REPO_PATH), diff --git a/tools/user-activity/pytest.ini b/tools/user-activity/pytest.ini new file mode 120000 index 0000000000..05a82dbfef --- /dev/null +++ b/tools/user-activity/pytest.ini @@ -0,0 +1 @@ +../../sdk/python/pytest.ini \ No newline at end of file diff --git a/tools/user-activity/setup.py b/tools/user-activity/setup.py index 8611fa47a1..a455a87fe7 100755 --- a/tools/user-activity/setup.py +++ b/tools/user-activity/setup.py @@ -3,7 +3,6 @@ # # SPDX-License-Identifier: AGPL-3.0 -from __future__ import absolute_import import os import sys import re