Browse Source

Add symlink metadata command to prep mirror nodes after deploy

Jordi Boggiano 6 years ago
parent
commit
996a8469af

+ 77 - 0
src/Packagist/WebBundle/Command/SymlinkMetadataMirrorCommand.php

@@ -0,0 +1,77 @@
+<?php
+
+/*
+ * This file is part of Packagist.
+ *
+ * (c) Jordi Boggiano <j.boggiano@seld.be>
+ *     Nils Adermann <naderman@naderman.de>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Packagist\WebBundle\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Filesystem\Filesystem;
+
+/**
+ * @author Jordi Boggiano <j.boggiano@seld.be>
+ */
+class SymlinkMetadataMirrorCommand extends Command
+{
+    public function __construct(string $webDir, string $metadataDir, array $awsMetadata)
+    {
+        $this->webDir = realpath($webDir);
+        $this->buildDir = $metadataDir;
+        $this->awsMeta = $awsMetadata;
+        parent::__construct();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function configure()
+    {
+        $this
+            ->setName('packagist:symlink-metadata')
+            ->setDefinition(array())
+            ->setDescription('Symlinks metadata dir to the mirrored metadata, if needed')
+        ;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function execute(InputInterface $input, OutputInterface $output)
+    {
+        if (empty($this->awsMeta) || !$this->awsMeta['is_web'] || $this->awsMeta['primary']) {
+            return 0;
+        }
+
+        $verbose = (bool) $input->getOption('verbose');
+
+        $sources = [
+            $this->buildDir.'/p',
+            $this->buildDir.'/p2',
+            $this->buildDir.'/packages.json',
+            $this->buildDir.'/packages.json.gz',
+        ];
+
+        foreach ($sources as $source) {
+            $target = $this->webDir.'/'.basename($source);
+            if (file_exists($target) && is_link($target) && readlink($target) === $source) {
+                continue;
+            }
+            if (!symlink($source, $target)) {
+                echo 'Warning: Could not symlink '.$source.' into the web dir ('.$target.')';
+                throw new \RuntimeException('Could not symlink '.$source.' into the web dir ('.$target.')');
+            }
+        }
+
+        return 0;
+    }
+}

+ 1 - 1
src/Packagist/WebBundle/Controller/HealthCheckController.php

@@ -58,7 +58,7 @@ class HealthCheckController
         }
 
         $runner->addCheck(new Check\DiskUsage(80, 90, '/'));
-        if ($this->awsMeta['primary'] === true) {
+        if ($this->awsMeta['has_instance_store'] === true) {
             $runner->addCheck(new Check\DiskUsage(80, 90, '/mnt/sdephemeral'));
         }
         $runner->addCheck(new Check\DiskFree(100 * 1024 * 1024, '/tmp'));

+ 37 - 29
src/Packagist/WebBundle/HealthCheck/MetadataDirCheck.php

@@ -21,40 +21,48 @@ class MetadataDirCheck extends AbstractCheck
     public function check()
     {
         if ($this->awsMeta['primary']) {
-            // TODO in symfony4, use fromShellCommandline
-            $proc = new Process('lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL | grep Instance | grep sdeph');
-            if (0 === $proc->run()) {
-                return new Success('Instance store is in use');
+            if ($this->awsMeta['has_instance_store']) {
+                // TODO in symfony4, use fromShellCommandline
+                $proc = new Process('lsblk -io NAME,TYPE,SIZE,MOUNTPOINT,FSTYPE,MODEL | grep Instance | grep sdeph');
+                if (0 !== $proc->run()) {
+                    return new Failure('Instance store needs configuring');
+                }
             }
 
-            return new Failure('Instance store needs configuring');
-        } else {
-            $packagesJson = __DIR__ . '/../../../web/packages.json';
+            $packagesJson = __DIR__ . '/../../../../web/packages.json';
+
             if (!file_exists($packagesJson)) {
-                return new Failure($packagesJson.' not found');
-            }
-            if (!is_link($packagesJson)) {
-                return new Failure($packagesJson.' is not a symlink');
-            }
-            if (substr(file_get_contents($packagesJson), 0, 1) !== '{') {
-                return new Failure($packagesJson.' does not look like it has json in it');
-            }
-            $metaDir = __DIR__ . '/../../../web/p';
-            $metaV2Dir = __DIR__ . '/../../../web/p2';
-            if (!is_dir($metaDir)) {
-                return new Failure($metaDir.' not found');
-            }
-            if (!is_link($metaDir)) {
-                return new Failure($metaDir.' is not a symlink');
-            }
-            if (!is_dir($metaV2Dir)) {
-                return new Failure($metaV2Dir.' not found');
-            }
-            if (!is_link($metaV2Dir)) {
-                return new Failure($metaV2Dir.' is not a symlink');
+                return new Failure($packagesJson.' not found on primary server');
             }
 
-            return new Success('Metadata mirror is symlinked');
+            return new Success('Primary server metadata has been dumped');
+        }
+
+        $packagesJson = __DIR__ . '/../../../../web/packages.json';
+        if (!file_exists($packagesJson)) {
+            return new Failure($packagesJson.' not found');
+        }
+        if (!is_link($packagesJson)) {
+            return new Failure($packagesJson.' is not a symlink');
+        }
+        if (substr(file_get_contents($packagesJson), 0, 1) !== '{') {
+            return new Failure($packagesJson.' does not look like it has json in it');
+        }
+        $metaDir = __DIR__ . '/../../../../web/p';
+        $metaV2Dir = __DIR__ . '/../../../../web/p2';
+        if (!is_dir($metaDir)) {
+            return new Failure($metaDir.' not found');
         }
+        if (!is_link($metaDir)) {
+            return new Failure($metaDir.' is not a symlink');
+        }
+        if (!is_dir($metaV2Dir)) {
+            return new Failure($metaV2Dir.' not found');
+        }
+        if (!is_link($metaV2Dir)) {
+            return new Failure($metaV2Dir.' is not a symlink');
+        }
+
+        return new Success('Metadata mirror is symlinked');
     }
 }

+ 2 - 0
src/Packagist/WebBundle/Resources/config/services.yml

@@ -13,6 +13,8 @@ services:
             $databaseName: '%database_name%'
             $databaseUser: '%database_user%'
             $databasePassword: '%database_password%'
+            $webDir: '%kernel.root_dir%/../web/'
+            $metadataDir: '%packagist_metadata_dir%'
 
     Packagist\WebBundle\Command\:
         resource: '../../Command/*'