anotaciones que no quiero recordar, ni olvidar

me

Blog Técnico

Pasos para trasladar una web de servidor

Ratio: 0 / 5

Inicio inactivoInicio inactivoInicio inactivoInicio inactivoInicio inactivo

Esta es una de esas cosas que después de 10 años sigo repitiendo....
Vamos allá:

Hay que trasladar:

1.- La web (y  su base de datos)
2.- El correo
3.- El dominio

Este es el orden.

Paso 1, para hacerlo necesitaremos acceso FTP al servidor viejo del cliente y quizás acceso al panel de hosting o la base de datos.
Una vez descargada la vieja web, necesitaremos subirla al nuevo servidor y cambiar, si es necesario el archivo de configuración de la web, el cual contendrá la ruta vieja, o el usuario y clave viejos de la base de datos.

Paso 2, necesitamos crear las antiguas cuentas de correo en el nuevo servidor.
Cómo el correo no es algo que se pueda descargar vía FTP, si te saltas este paso, tu cliente perderá los correos: Cómo no perder los correos al cambiar un dominio de servidor

Paso 3, aunque crees el nuevo sitio en el servidor, y este haya creado las nuevas zonas DNS, el dominio sigue apuntando al viejo servidor. Tenemos entonces 2 cuestiones:
- DNS, que es a donde apunta el dominio (ahora mismo al viejo servidor)
- Quien se encarga de controlar, o sea renovar el dominio (ahora mismo al viejo proveedor de hosting)
Hay que migrar las dos cosas, pero no hace falta que sean a la vez, yo suelo cambair las DNS antes, si tengo acceso al viejo panel.
Para cambiar el control de dominio has de pedir que los desbloqueen y pedir el código de autorización "auth-code". Una vez solicitado el cambio de control, puede tardar en hacerse efectivo, hasta 5 días. Lo bueno es que aunque tarde el servicio nunca se corta.
Para cambiar las DNS lo primero que debes saber es que dicho cambio puede tardar de unas horas, hasta 2 días. Y en este caso el servicio si que puede cortarse, pero no te alarmes, normalmente si se cambian las DNS a las 8 de la tarde, a la mañana siguiente a primera hora ya se ha hecho efectivo.

Cómo no perder los correos al cambiar un dominio de servidor

Ratio: 5 / 5

Iniciar activoIniciar activoIniciar activoIniciar activoIniciar activo

Una pregunta clásica de los clientes, que no se porqué aun no había respondido por escrito. Hay una solución muy tonta, pero compatible con tooodos los servidores.

Si usas POP3 no hay problema, si usas IMAP sigue estos pasos:

Paso 1: Antes de cambiar las DNS del dominio, con algún programa como Thunderbird, crea la misma cuenta de correo en tipo POP3. Se supone que ya la tienes creada en modo IMAP. (Al crearla como POP3 te recomiendo que en la configuración marques la casilla de dejar los correos copiados en el servidor para que no dejen de estar mientras)

Paso 2: Descarga los correos.

Paso 3: Cambia las DNS del dominio y espera a que se actualicen a nivel mundial (24/48 horas)

Paso 4: Abre ThunderBird y ves a la cuenta en modo POP3 y arrastra los correos de la bandeja de entrada y de enviados (los correos, repito), a las correspondientes carpetas IMAP.

Fin.

Error al reiniciar la configuración de red: RTNETLINK answers: File exists Failed to bring up eth0

Ratio: 3 / 5

Iniciar activoIniciar activoIniciar activoInicio inactivoInicio inactivo

Si al ejecutar un reinicio de la red:

Mostrar/Ocultar código bash

Ver código
/etc/init.d/networking restart

Se nos muestra:

Mostrar/Ocultar código bash

Ver código
RTNETLINK answers: File exists 
Failed to bring up eth0

Debemos, antes del reinicio de red, eliminar la caché con un:

Mostrar/Ocultar código bash

Ver código
ip addr flush dev eth0

Limitar la velocidad de subida de vídeos a Youtube en Linux

Ratio: 0 / 5

Inicio inactivoInicio inactivoInicio inactivoInicio inactivoInicio inactivo

Mi fin es Youtube, pero en realidad lo que vamos a hacer limita cualquier proceso o hilo de subida o bajada.
Instalamos wondershaper:

Mostrar/Ocultar código bash

Ver código
sudo apt-get install wondershaper

Y luego le decimos que por ejemplo cada proceso o hilo no supere los 100 MB de bajada y los 2MB de subida, pero en kilobytes:
(Si estas conectado por wifi cambia eth0 por wlan0)

Mostrar/Ocultar código bash

Ver código
sudo wondershaper eth0 100000 2000

Y ya podemos empezar la subida.

Usuarios registrados no pueden logearse / acceder a la págin a web, error 500 o: Usted no puede acceder a la sección privada de este sitio.

Ratio: 5 / 5

Iniciar activoIniciar activoIniciar activoIniciar activoIniciar activo

Y después de toda la verborrea del titulo diré que Joomla, como todos los sistemas multi-plugins, multi-desarrolladores, multi-extensiones, multi-plataformas, etc, a veces fallan y no sabes por donde cogerlos. Porque aunque vayas a la carpeta "log" en el raiz de tu sitio, puede que sea cómo este caso, que no hay mayor información del error.

Si no has tocado los permisos de los usuarios (Configuración > Pestaña Permisos) quizás hayas tenido el problema de los permisos "Assets" de los componentes. El cual puedes arreglar garcias al foro joomla aquí:

Mostrar/Ocultar código mysql

Ver código
UPDATE `prefix_assets` SET `parent_id`=1 WHERE `parent_id`=0 AND id>1
UPDATE `prefix_assets` SET `parent_id`=0 WHERE `title` = 'Root Asset'

O con un script de ElinW, subido a GitHub aquí, algo más completo que deberás subir al raiz de tu sitio. A fecha de hoy contiene esto, dejo una copia por si acaso:

Mostrar/Ocultar código php

Ver código
<?php
/**
 * A JApplicationWeb application built on the Joomla Platform.
 *
 * To run this place it in the root of your Joomla CMS installation.
 * This application is buil
 *
 * @package    Joomla.AssetFix
 * @copyright  Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
 * @license    GNU General Public License version 2 or later; see LICENSE
 */
 
//ini_set('display_errors','1');
error_reporting(-1);
ini_set('display_errors', 'On');
 
// Set flag that this is a parent file.
// We are a valid Joomla entry point.
define('_JEXEC', 1);
 
// Setup the base path related constants.
define('JPATH_BASE', dirname(__FILE__));
define('JPATH_SITE', JPATH_BASE);
define('JPATH_CONFIGURATION',JPATH_BASE);
 
// Bootstrap the application.
require JPATH_BASE . '/libraries/import.php';
 
 
// Import the JApplicationWeb class from the platform.
// IS_MAC is not defined in the CMS 3 version of the platform.
if (!defined('IS_MAC'))
{
    define('JPATH_LIBRARIES', JPATH_PLATFORM);
    require JPATH_BASE . '/libraries/import.legacy.php';
    require JPATH_BASE . '/libraries/cms.php';
 
    // Import the JApplicationWeb class from the platform.
    JLoader::import('joomla.application.web');
    JLoader::import('cms.helper.tags');
    JLoader::import('cms.table.corecontent');
    JLoader::import('joomla.observer.mapper');
    // Categories is in legacy for CMS 3 so we have to check there.
    JLoader::registerPrefix('J', JPATH_PLATFORM . '/legacy');
    JLoader::Register('J', JPATH_PLATFORM . '/cms');
}
/**
 * This class checks some common situations that occur when the asset table is corrupted.
 */
// Instantiate the application.
class Assetfix extends JApplicationWeb
{
 
    /**
     * Overrides the parent doExecute method to run the web application.
     *
     * This method should include your custom code that runs the application.
     *
     * @return  void
     *
     * @since   11.3
     */
 
    public function __construct()
    {
        // Call the parent __construct method so it bootstraps the application class.
        parent::__construct();
        require_once JPATH_CONFIGURATION.'/configuration.php';
 
        jimport('joomla.database.database');
 
        // System configuration.
        $config = JFactory::getConfig();
 
        // Note, this will throw an exception if there is an error
        // Creating the database connection.
        $this->dbo = JDatabase::getInstance(
            array(
                'driver' => $config->get('dbtype'),
                'host' => $config->get('host'),
                'user' => $config->get('user'),
                'password' => $config->get('password'),
                'database' => $config->get('db'),
                'prefix' => $config->get('dbprefix'),
            )
        );
 
    }
 
    protected function doExecute()
    {
        // Initialise the body with the DOCTYPE.
        $this->setBody(
            '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
        );
 
        $this->appendBody('<html>')
            ->appendBody('<head>')
 
            ->appendBody('</head>')
            ->appendBody('<body style="font-family:verdana; margin-left: 30px; width: 500px;">');
 
        $this->appendBody('<h1>Asset Fix</h1>
            <p>This is an unofficial way of fixing the asset table for extensions, categories and articles</p>
            <p>It attempts to fix some of the reported issues in asset tables, but is not guaranteed to fix everything</p>'
        );
 
            $this->_db = JFactory::getDBO();
 
            $contenttable =  JTable::getInstance('Content');
            $asset = JTable::getInstance('Asset');
 
            $asset->loadByName('root.1');
            if ($asset)
            {
                $rootId = (int) $asset->id;
            }
 
            if ($rootId && ($asset->level != 0 || $asset->parent_id != 0))
            {
                self::fixRoot($rootId);
            }
 
            if (!$asset->id)
            {
                $rootId = self::getAssetRootId();
                self::fixRoot($rootId);
            }
 
            if ($rootId === false)
            {
                // Should the row just be inserted here? 
                $this->appendBody('<p>There is no valid root. Please manually create a root asset and rerun.</p>');
            }
            if ($rootId)
            {
                // Now let's make sure that the components  make sense
                $query = $this->_db->getQuery(true);
                $query->select('extension_id, name');
                $query->from($this->_db->quoteName('#__extensions'));
                $query->where($this->_db->quoteName('type') . ' = ' . $this->_db->quote('component'));
                $this->_db->setQuery($query);
                $components = $this->dbo->loadObjectList();
 
                foreach ($components as $component)
                {
                    $asset->reset();
                    $asset->loadByName($component->name);
 
                    if ($asset && ($asset->parent_id !=  $rootId || $asset->level != 1))
                    {
                        self::fixExtensionAsset($asset,$rootId);
                        $this->appendBody('<p>This asset for this extension was fixed: ' . $component->name . '</p>');
                    }
                    elseif (!$asset)
                    {
                        $this->appendBody('<p>This extension is missing an asset: ' . $component->name . '</p>');
                    }
                }
 
                // Let's rebuild the categories tree
                JTable::getInstance('Category')->rebuild();
 
                // Although we have rebuilt it may not have fully worked. Let's do some extra checks.
                $asset = JTable::getInstance('Asset');
                
                $assetTree = $asset->getTree(1);
 
                // Get all the categories as objects
                $queryc = $this->_db->getQuery(true);
                $queryc->select('id, asset_id, parent_id');
                $queryc->from('#__categories');
                $this->_db->setQuery($queryc);
                $categories = $this->dbo->loadObjectList();
 
                // Create an array of just level 1 assets that look like the are extensons. 
 
                $extensionAssets = array();
 
                foreach ($assetTree as $aid => $assetData)
                {
                        // Now we will make a list of components based on the assets table not the extensions table.
                        if (substr($assetData->name, 0, 4) === 'com_' && $assetData->level ==1)
                        {
                                $extensionAssets[$assetData->title] = $assetData->id;
                        }
                }
 
                foreach ($assetTree as $assetData)
                {
                    // Assume the root asset is valid.
                    if ($assetData->name != 'root.1')
                    {
                        // There have been some reports of misnamed contact assets.
                        if (strpos($assetData->name, 'contact_details') != false)
                        {
                            str_replace($assetData->name, 'contact_details', 'contact');
                        }
 
                        // Now handle categories with parent_id of 0 or 1
                        if (strpos($assetData->name, 'category') != false)
                        {
                            $catFixCount = 0;
                            $fixedCats = array();
                            // Just assume that they are top level categories.
                            // We are also goingto fix parent_id of 1 since some people in the forums did this to temporarily
                            // fix a problem and also categories should never have a parent_id of 1.
                            if ($assetData->parent_id == 0 || $assetData->parent_id == 1)
                            {
                                $catFixCount += 1;
                                $explodeAssetName = explode('.', $assetData->name);
                                $assetData->parent_id = $extensionAssets[$explodeAssetName[0]];
                                $fixedCats[] = $assetData->id;
    
                                $asset->load($assetData->id);
                                // For categories the ultimate parent is the extension
                                $asset->parent_id = $extensionAssets[$explodeAssetName[0]];
                                $asset->store();
                                $asset->reset();
 
                                $this->appendBody('<p>The assets for the following category was fixed:' . $assetData->name . ' You will want to
                                check the category manager to make sure any nesting you require is in place.');
                            }
                        }
                    }
                }
 
                // Rebuild again as a final check to clear up any newly created inconsistencies.
                JTable::getInstance('Category')->rebuild();
                $this->appendBody('<p>Categories were successfully finished.</p>');
 
                // Now we will start work on the articles
                $query = $this->_db->getQuery(true);
                $query->select('id, asset_id');
                $query->from('#__content');
                $this->_db->setQuery($query);
                $articles = $this->dbo->loadObjectList();
 
                foreach ($articles as $article)
                {
                    $asset->id = 0;
                    $asset->reset();
                    
                    // We're going to load the articles by asset name.
                    if ($article->id > 0)
                    {
                        $asset->loadByName('com_content.article.' . (int) $article->id);
                        $query = $this->_db->getQuery(true);
                        $query->update($this->_db->quoteName('#__content'));
                        $query->set($this->_db->quoteName('asset_id') . ' = ' . (int) $asset->id);
                        $query->where('id = ' . (int) $article->id);
                        $this->dbo->setQuery($query);
                        $this->dbo->query();
                    }
 
                    //  JTableAssets can clean an empty value for asset_id but not a 0 value. 
                    if ($article->asset_id == 0)
                    {
                        $article->asset_id = '';
                    }
                    $contenttable->load($article->id);
                    $contenttable->store();
                }
 
                $this->appendBody('<p>Article assets successfully finished.</p>');
 
            $this->appendBody('</li>');
            $this->appendBody('</li>
            </ul>');
            }
 
        // Finish up the HTML response.
        $this->appendBody('</body>')
            ->appendBody('</html>');
    }
 
    protected function fixRoot($rootId)
    {
        // Set up the proper nested values for root
        $queryr = $this->_db->getQuery(true);
        $queryr->update($this->_db->quoteName('#__assets'));
        $queryr->set($this->_db->quoteName('parent_id') . ' = 0 ')
            ->set($this->_db->quoteName('level') . ' =  0 ' )
            ->set($this->_db->quoteName('lft') . ' = 1 ')
            ->set($this->_db->quoteName('name') . ' = ' . $this->_db->quote('root.' . (int) $rootId));
        $queryr->where('id = ' . (int) $rootId);
        $this->dbo->setQuery($queryr);
        $this->dbo->query();
 
        return;
    }
 
    /**
     * Fix the asset record for extensions
     * 
     * @param  JTableAsset  $asset   The asset table object
     * @param   integer     $rootId  The primary key value for the root id, usually 1.
     *
     * @return  mixed  The primary id of the root row, or false if not found and the internal error is set.
     *
     * @since   11.1
     */
    protected function fixExtensionAsset($asset, $rootId = 1)
    {
        // Set up the proper nested values for an extension
        $querye = $this->_db->getQuery(true);
        $querye->update($this->_db->quoteName('#__assets'));
        $querye->set($this->_db->quoteName('parent_id') . ' =  ' . $rootId )
            ->set($this->_db->quoteName('level') . ' = 1 ' );
        $querye->where('name = ' . $this->_db->quote($asset->name));
        $this->dbo->setQuery($querye);
        $this->dbo->query();
 
        return;
    }
 
    /**
     * Gets the ID of the root item in the tree
     *
     * @return  mixed  The primary id of the root row, or false if not found and the internal error is set.
     *
     * @since   11.1
     */
    public function getAssetRootId()
    {
        // Test for a unique record with parent_id = 0
        $query = $this->dbo->getQuery(true);
        $query->select($this->dbo->quote('id'))
            ->from($this->dbo->quoteName('#__assets'))
            ->where($this->dbo->quote('parent_id') .' = 0');
 
        $result = $this->dbo->setQuery($query)->loadColumn();
 
        if (count($result) == 1)
        {
            return $result[0];
        }
 
        // Test for a unique record with lft = 0
        $query = $this->dbo->getQuery(true);
        $query->select('id')
            ->from($this->_db->quoteName('#__assets'))
            ->where($this->_db->quote('lft') . ' = 0');
 
        $result = $this->_db->setQuery($query)->loadColumn();
 
        if (count($result) == 1)
        {
            return $result[0];
        }
 
        // Test for a unique record alias = root
        $query = $this->_db->getQuery(true);
        $query->select($this->_db->quoteName('id'))
            ->from($this->_db->quoteName('#__assets'))
            ->where('name LIKE ' . $this->_db->quote('root%'));
 
        $result = $this->_db->setQuery($query)->loadColumn();
 
        if (count($result) == 1)
        {
            return $result[0];
        }
 
        $e = new UnexpectedValueException(sprintf('%s::getRootId', get_class($this)));
        //$this->setError($e);
 
        return false;
    }
}
JApplicationWeb::getInstance('Assetfix')->execute();