• #9 Web2py: <type 'exceptions.ValueError'> insecure string pickle

    2018-09-04 13:01:27

    Não reza a história mas há um 11º mandamento perdido das tábuas do Moisés. Na altura ninguém sabia o que era um servidor, por isso os deuses, na sua infinita sabedoria, ordenaram ocultar este 11º mandamento para não criar confusão nos povos primitivos da altura, ficando para a posteridade. Diz o seguinte:

    «Não atualizarás servidores perto de fins-de-semanas ou dias de festa»

    Cometi tabu, o sacrilégio máximo dos webmasters: atualizei um servidor na primeira semana de agosto, faltava uma semana para começarem as férias. Sempre que o faço sinto-me como num filme, a tentar cortar o fio vermelho quando faltam cinco segundos para a bomba explodir. Fazê-lo tão perto das férias dramatiza a situação: é tentar cortar o fio vermelho, sentado numa ogiva nuclear em pleno voo, rodeado de 50 fios com tonalidades mais claras de vermelho, com um martelo em vez de alicate e luvas de boxe.

    Exageros há parte: normalmente corre bem e foram atualizações básicas. Desta vez foi exceção e uma em particular quebrou-me uma dúzia de sites mais antigos: passei a framework Web2py (O.S. Ubuntu, Server Nginx) da versão R-2.14.6 (ou anterior, não recordo) para a versão R-2.16.1. Eles são impecáveis e asseguram retrocompatibilidade, mas esta foi a única exceção (é normal, no meio de tantos cenários é impossível cobrir tudo). Felizmente apenas influenciou websites criados com a base mais antiga da framework que poucos usam (criados antes de 2015), não tocou nos sites mais recentes com coisas a decorrer, por isso não tive de adiar as férias, bastou um "temporarily down for maintenance" nesses casos. Inspecionando os "error tickets" o erro era "<type 'exceptions.ValueError> insecure string pickle" e tinha origem nos ficheiros que definiam as migrations da base de dados.

    Uma das primeiras missões na vinda das férias foi corrigir isto. A coisa mais grave que ficou offline foi o painel de gestão de uma biblioteca com 12 mil registos dos empréstimos de livros ausentes - mas felizmente a biblioteca esteve fechada para obras até esta semana e não precisavam deles com urgência. Depois de alguma pesquisa e espreitadela nos logs eis a solução:

    - O problema são os ficheiros ".table" corrompidos/incompatíveis - são apenas ficheiros gerados pela DAL para gerir as migrations da base de dados, não afeta os dados em si. Para corrigir, basta apagar todos os ficheiros com extensão ".table" na pasta "databases" (por default), na raiz do website - nota: se o website usar SQLite o ficheiro com os dados estará também nesse diretório entre os ".table" (com extensão ".sqlite"), não apagar ou a base de dados hasta la vista! Depois disso basta ir ao ficheiro com a instanciação principal da base de dados e ativar uma fake migration para o sistema gerar novos ficheiros ".table", ou seja, partindo do pressuposto que estão em uso os directórios/ficheiros default: em /models/db.py na linha que define a db acrescentar o atributo "fake_migrate_all=True", por default essa linha é semelhante a:

    db = DAL('sqlite://storage.sqlite',pool_size=1,check_reserved=['all'])

    Depois disso basta lançar uma página do site, para obrigar a criação dos infames ".table", o erro deverá desaparecer nessa altura. Por último basta apagar o "fake_migrate_all=True" para desligar a fake migration (assume False por default) e voilà la, tudo deverá voltar ao normal. No meu caso este erro ocorreu principalmente em websites antigos (>2015), que usam uma base antiga da framework, cujos ficheiros das migrations (".table") são incompatíveis com as versões recentes.

    Nota: um 12º mandamento dita que convém realizar um backup da base de dados antes de tentar indicações em posts de estranhos da internet.

    Isto fica aqui para aparecer nas pesquisas do google caso alguém precise.

    () comentários