Acertando a Hora *Unix – ntpdate

Essa vai ser uma dica rápida. Como acertar a hora em sistemas *Unix (Linux, Freebsd, OpenBSD, etc).
Usuários Ubuntu precisam ter o programa instalado.

sudo aptitude install ntpdate

Acertando a hora

Vamos sincronizar a hora de nosso sistema com algum servidor público espalhado pelo mundo, no meu caso vou utilizar o da usp.

sudo ntpdate ntp.usp.br

Isso já é o suficiente para acertar o horário da sua máquina.

Vamos um pouco mais a fundo agora.

Eu tenho que garantir que meus servidores estão com a hora sincronizada, para tanto vou fazer essa essa atualização todos os dias 🙂 e para ficar ainda mais seguro vou fazer em 2 servidores diferentes 🙂 🙂

Segue o script para fazer essa atualização em uma máquina FreeBSD.

#!/usr/local/bin/bash
ntpdate=`which ntpdate`

#Lista de servers ntpdate espalhados pelo mundo pode-se adicionar quantos quiser separados por espaço
SERVERS="ntp.pool.org ntp.usp.br"

for server in $SERVERS
do 
   $ntpdate $server
done   

Esse script deve ser salvo e precisa estar com permissão de execução ( chmod +x atualizaHora.sh ) após isso foi enviado para a pasta /usr/local/etc/periodic/daily onde será executado todos os dias.

Esse procedimento poderia ser feito pelo crontab também, mas ao preferi coloca-lo nesta pasta pois ela já é chamada via crontab do root.

Complementando a informação a porta de entrada e saida do NTPDATE é a 123 isso mesmo 123, sendo assim essa porta deve estar aberta no firewall da máquina que se deseja sincronizar.

Outros servers ntpdate

  • time.windows.com
  • time.apple.com
  • ntp.ufrj.br
  • ntp.ubuntu.com

Pronto hora ajustada, então é hora de partir.
Abraços.

Tags: , , ,

Find, rsync, svn, scp Ferramentas do desenvolvedor

Acompanho o twitter de varios desenvolvedores e vire e mexe alguém esta com alguma reclamação com seus arquivos versionados tipicamente estes arquivos são os “.svn” .

Os arquivos svn são pastas que contem a assinatura dos arquivos e seus conteúdos, ou seja tudo fica duplicado,  e algumas vezes quando vamos enviar esses arquivos para o servidor de produção não nos atentamos que estamos enviando junto os arquivos svn o que faz a transferencia ficar muito mais lenta pois tem que se enviar muito mais arquivos.

Hoje vejo que isso pode ser contornado de 3 formas diferentes:

Baixando as Atualizações via svn

Nesta modalidade o desenvolvedor envia todos os seus códigos para o servidor de svn “svnserver”,
mas antes verifica se algo entrou em conflito ou se ele próprio precisa fazer alguns updates.

svn status -u /url/pasta/raiz/projeto/

Imaginando que tudo esta correto e que somente ele tem arquivos a serem enviados.

svn commit -m "SEU COMENTÁRIO" /url/do/arquivo/a/ser/commitado/
svn commit -m "SEU COMENTÁRIO" /url/da/pasta//commitada/

Pronto tudo esta pronto e devidamente no seu lugar, agora vamos logar na máquina de produção e fazer o update que foi enviado.

svn update /url/pasta/raiz/projeto/

Neste modo nada se perde no caminho. Fim todo mundo feliz

Mandando pequenas atualizações que ainda não são a versão final do arquivo

Nesta modalidade o desenvolvedor envia todos os seus códigos para o servidor de testes, portanto não importa se vai haver svn ou não. O que importa aqui seria ser um pouco mais rápido.

Ai ele limpa todos os .svn para ficar mais leve o envio.

cp -R /url/pasta/raiz/projeto/ /tmp/projeto
find /tmp/projeto -iname *.svn -exec rm -rf {} \;

Assim foram apagados todos os arquivos .svn da pasta do projeto pois esse foi copiado para o /tmp/projeto
Assim só precisamos enviar os novos arquivos para o servidor TESTE , leia-se TESTE e não “DE TESTE”

scp -r /tmp/projeto/arquivo/ usuario@host:/url/pasta/raiz/projeto/

Os arquivos são enviados e todos quase ficamos felizes, pois essa não é a melhor prática.

Mandando pequenas atualizações que ainda não são a versão final do arquivo por rsync

Esta é a caracteristica do rsync que achei interessante pois não conhecia a syntaxe.
A opção -C do rsync exclui uma penca de arquivos que normalmente eu apagava na mão, e evita que se tenha que copiar para um segundo diretorio todos os arquivos para depois limpa-los.
Sendo assim enviando para o mesmo sever bastaria fazer o seguinte.

rsync -Cavz -e ssh /url/pasta/raiz/projeto/  usuario@host:/url/pasta/raiz/projeto

Todos os arquivos que foram modificados serão enviados e com a vantagem de ser descartados esses tipos de arquivo.

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~ #* .#* ,* _$* *$  *.old  *.bak  *.BAK  *.orig *.rej .del-* *.a *.olb *.o *.obj *.so *.exe *.Z *.elc *.ln core .svn/

Como tem alguns desenvolvedores que mesmo sob um sistema de controle de versão (svn) continuam usando o “.old” o rsync também os ignora, isso é simplesmente lindo!

Essas são algumas práticas que tenho observado no twitter e também com companheiros de trabalho.

Acho que essas dicas podem ajudar alguém por isso postei esses detalhes.

E existem também muitas outras maneiras de fazer esse deploy. Invente a sua ….

O Zen do Python

A alguns dias descobri uma coisa bem interessante no python.  Ao fazer o import dele mesmo ele mostra alguns principios que foram criados por  Tim Peters.

Seguindo a risca esses principios dificilmente seu projeto vai dar errado 😛

Como os encontro?

Em sua linha de comando (estou assumindo que  você esta em algum Unix e que tenha python instalado) digite:

$ python

Neste momento você estará entrando no shell interativo do python depois é só fazer o import.

 import this

O resultado você visualiza abaixo

Python 2.5.2 (r252:60911, Oct  5 2008, 19:24:49)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

Vou colocar também uma livre tradução que encontrei na internet e que cito o autor abaixo.

Bonito é melhor que feio.
Explícito é melhor que implícito.
Simples é melhor que complexo.
Complexo é melhor que complicado.
Plano é melhor que aninhado.
Esparso é melhor que denso.
Legibilidade conta.
Casos especiais não são especiais o bastante para se quebrar as regras.
Embora a simplicidade supere o purismo.
Erros nunca deveriam passar silenciosamente.
A menos que explicitamente silenciados.
Ao encarar a ambiguidade, recuse a tentação de adivinhar.
Deveria haver uma – e preferencialmente apenas uma – maneira óbvia de se fazer isto.
Embora aquela maneira possa não ser óbvia à primeira vista se você não for holandês.
Agora é melhor que nunca.
Embora nunca, seja muitas vezes melhor que pra já.
Se a implementação é difícil de explicar, é uma má idéia.
Se a implementação é fácil de explicar, pode ser uma boa idéia.
Namespaces são uma idéia estupenda – vamos fazer mais deles!

fonte da tradução

Básicamente são boas maneiras para se trabalhar com python.

Algumas coisas que senti falta e que vou acrescer ao texto

Marretas não são bem vindas, mas são necessárias.
O pior código é aquele que não existe, esse não dá dinheiro

Bem acho que é isso que tinha a dizer hoje.

Fui ….

Fontes:

http://www.python.org/dev/peps/pep-0020/

http://pipeless.blogspot.com/2008/09/o-zen-de-python.html

Tags: , ,

Utilizando a Classe Set do Python

Recentemente fiz uma aplicação onde tinha que verificar a diferença entre algumas estrutura de dados inicialmente fiz na mão mesmo, mas não me conformei com isso e resolvi fazer uma pesquisa para saber como se faz isso no python.

Encontrei uma classe que trabalha com todas as ações básicas dos conjuntos.

Obs.: Fiz uns exemplos básicos e que para alguns podem parecer sem sentido mas server  apenas para mostrar os conceitos da classe.

Vamos lá então, primeiro vou criar uma estrutura de dados que vou chamar de opções isso poderia estar vindo de uma banco de dados ou mesmo lendo um arquivo TXT.

Povoando nossas opções.

 opcoes =  [9, 3, 6, 5, 0, 1, 7, 2, 8, 4]

E inicializaremos nossas bases de números impares e pares.

pares = []
impares = []

#Gerando duas novas listas a partir das opções dadas
for numero in opcoes:
    if numero % 2 == 0:
        pares.append(numero)
    else:
        impares.append(numero)

Para que possamos trabalhar com a classe SET a origens de dados devem ser do tipo SET também.

opcoes  = set(opcoes)
pares   = set(pares)
impares = set(impares)

Agora vamos começar os testes. OBA!!!!

#Descobrir dentre as opções descobrir quais estão no grupo dos pares
opcoesPares = set.intersection( opcoes, pares )

#Descobrir dentre as opções descobrir quais estão no grupo dos impares
opcoesImpares = set.intersection( opcoes, pares )

#Fazendo  a união das duas listas
paresMaisImpares = set.intersection( opcoesPares, opcoesImpares )

#Vamos verificar se o grupo dos pares são pertencentes ao grupo de opções
paresPertencemAOpecoes = set.issubset( pares, opcoes )

#Verificar o que tem de diferente entre as opções e os numeros impares
naoContemEssesNumerosNosImpares = set.difference( opcoes, impares )

Bem acho que é isso fiz alguns exemplos bem básicos e acredito que pode ser um ponto de partida para um estudo mais aprofundado então como última dica a respeito seria isso.

http://docs.python.org/library/sets.html

Mas se não tiver afim de ir para net pode ser por modo interativo mesmo.

$ python
Python 2.4.3 (#1, Jul 27 2009, 17:57:39)
[GCC 4.1.2 20080704 (Red Hat 4.1.2-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> help(set)

Se tiverem exemplos mais interessantes deixe nos comentários que serão devidamente divulgados com os nomes dos autores

Postgresql – Backup de todas as base de dados

postgresql

Motivado por esse post ( http://www.vivaolinux.com.br/dica/PostgreSQL-Fazendo-backup-de-um-servidor-inteiro ) resolvi fazer algumas adaptações para atender as minhas especificações.

Eu preciso ter backup do servidor inteiro mais não necessáriamente preciso retornar todas as bases para o novo servidor novamente, por esse motivo fiz o meu próprio script para resolver esse problema.

Utilizando a linguagem python associada aos aplicativos do postgresql montei esta rotina.

#!/usr/bin/env python
#! -*- coding:utf8 -*-
########################################################
#  Script para fazer o pg_dump de todos os
#   bancos da máquina em que ele for executado
#  Valdinei dos Santos
#  valdineidossantos(at)gmail.com.br
#  27 Julho de 2009
########################################################
#Importando o getstatusoutput responsavel por executar os comandos do sistema operacional
from commands import getstatusoutput
from datetime import datetime
from os import path

#config
psql="/usr/bin/psql"
pg_dump="/usr/bin/pg_dump"
user="pguser-vale"
host="valdineidossantos.com"
repository = "/media/backup/databases/"

#Functions
def getAllDatabases(psql, user, host):
    print "\nRecuperando as bases de dados do servidor %s" % host
    command = "%s -U %s -h %s -l" % (psql, user, host)
    status, output = getstatusoutput ( command )
    if int(status) == 0:
       #return lista de servidores
       return stringToListServers( output )
    else:
        return [[],] 

def stringToListServers( databaseString ):
    print "\nFormatando a string"
    temp_pieces = databaseString.split("\n")
    dataBases = []
    for i in temp_pieces[3:]:
        try:
            pieces = i.split("|")
            owner  = pieces[1].strip()
            dbName = pieces[0].strip()
            encode = pieces[2].strip()
            data   = [dbName, encode, owner]
            if data:
                dataBases.append ( data )
        except Exception, e:
            continue
            #print e.__doc__
    return dataBases

#Init
if __name__ == '__main__':

    allDataBases =  getAllDatabases(psql, user, host)

    day = datetime.now().strftime("%Y%m%d")
    for database, encode, owner in allDataBases:
        #name Example databasename-20092707.dump
        dumpName = "%s-%s.dump" % (database, day)    

        #/dev/null/databasename-20092707.dump
        file = path.join(repository, dumpName)

        command = "%s -U %s -h %s -E %s  -f %s -i -Fc %s " % (pg_dump, user, host, encode, file, database)

        status, output = getstatusoutput( command)

        if int(status) > 0:
            print "Erro no backup da database %s\n %s" % (database, output)

Após esse script finalizado teremos no diretorio que foi setado no config “repository” todos os bancos de dados disponiveis no servidor.
Para voltar novamente com a base dados para o novo servidor rodamos o comando.

pg_restore -d |nome da base dados| -Fc |caminho/nome do arquivo dump|

Temos algumas outras opções em shell script  mas preferi usar  o python  🙂
Python

Tags: , , ,

Ubuntu e seus updates.

Hoje fiz uma atualização de segurança do Ubuntu, não que eu sempre veja mas dessa vez eu nem passei o olho para saber o que se passava. Isso é um grande erro.
Essas atualização incluiam o pacote linux-restricted-modules-2.6.24-19-generic, feito todas as instalações pediu para reinciar o computador. Poxa mas isso é linux ou Windows? Me perguntei. Logo veio a resposta realmente estão reproduzindo o windows no Ubuntu. Resultado parcial, parou de funcionar minha rede sem fio e minha placa de som nem olhei o resto.
Vamos aos passos para sabermos o porque do não funcionamento.

Digite o comando
dmesg.

Com este comando eu visualizo as mensagens de carregamento do sistema, com muita paciência fui vendo linha a linha até encontrar algo que me parecece (é assim que se escreve?) estranho.
Achei a linha WL com uma mensagem de Fatal erro. Vamos ao passo dois que é copiar essa string (linha de palavras) e entrar no tio google para saber se alguém já teve esse problema.
Achei milhares de coisas relacionadas e algumas que não tinham nada haver.
Minha máquina é um notebook Inspiron 1525 da fabricante Dell, sendo assim sempre procurava entrar nas palavras relacionadas. Minhas palavras chaves eram Ubuntu, Inspiron, Dell, E o erro encontrado como saida do dmesg.
Achei um forum muito interessante em que alguém tinha o mesmo computador que o meu e o problema exatamente igual. Descobri que a Dell também tem um site com informações de ajuda e da comunidade.
Resumindo a historia pois já escrevi muito. Para que minha placa de som e Wireles voltasse a funcionar tenho que voltar a versão do linux-restrict. Fui no menu sistema->administração->Gerenciador de Pacotes Synaptic, e verifiquei as versões que existiam. Para meu espanto existia três versões do mesmo pacote só não sei para que.
Vamos resolver o problema, desinstalei todos os pacotes que não queria e deixei apenas o que realmente me interessava. Reinicie e no menu do Grub fui até a versão do linux-restrict 18 no modo recovery e pronto. Instalei a versão que estava funcional.
Para ter certeza que a versão errada não seja chamada novamente desinstalei a versão mais nova também. Agora com o sistema limpo e funcional fui no google de novo para saber a última informação.
E se este pacote defeituoso voltar a ser instalar no meu sistema? Existe uma flag que podemos adicionar ao comando aptitute para que esse pacote não seja atualizado sozinho. Não sei se funciona mas fiz o seguinte.

sudo aptitude hold linux-restricted-modules-2.6.24-18-generic
sudo aptitude hold linux-restricted-modules-common

Após essa longa jornada, só como detalhe perdi 3 horas fazendo todas essas tentativas, mandei o synaptic verificar por atualizações e ele respondeu que o sistema se encontrava com a versão mais recente. Então conclui que tudo estava direito e funcionando e o pacote com erro não entraria no meu sistema por discuido de não olhar o que vai ser instalado.

Ubuntu não vire windows, senão vou abandona-lo e vou voltar para FreeBSD.

Tags: , , , , , ,

Videos no Ubuntu

Ver vídeos no ubuntu já é uma tarefa simples, mas recebi um no formato .wmv (Windows Movie). O Ubuntu até consegue abrir o arquivo mas as imagens e sons não são apresentados.
Para resolver o problema fui ao bom e velho google, procurei achei algumas referencias mas os tutoriais sempre apontavem para links inexistentes, sendo assim vou fazer um mais atual 🙂

Primeiro passo vou instalar meu player de Vídeo favorito, se você já tiver seu player favorito (Mplayer, Xine, Totem) não precisa fazer esse passo.

sudo aptitude install vlc

Aceite as opções que ele sugere e pronto, player instalado.
Passo dois encontrar o codec do maldito windows wmv (w32codes). Com o navegador web (opera, firefox, konqueror, IE não ele não é um navegador web) vá até esse endereço:

http://ftp.sunet.se/pub/os/Linux/distributions/debian-multimedia/pool/main/w/w32codecs

Neste endereço serão exibidos alguns arquivos o que realmente interessa para nós é o w32codecs_XXXXXX.deb onde XXXX é a versão do arquivo que vc vai baixar.
Clique no pacote .deb e o browser vai pedir para salvar o arquivo, você escolha um diretorio onde consiga lembrar depois e clique em ok.
Após o download concluido, quando fiz era em torno de 14MB, você fará a instalação do arquivo baixado.

Quando fui instalar o w32codecs no meu sistema existia uma dependencia que estava faltando sendo assim tive que instalar:

sudo aptitude install libstdc++5

Faça o comando acima caso você já o tenha no sistema não será afetado em nada sua instalação.
Agora vamos ao pacote baixado, navegue no terminal até a pasta onde você salvou o arquivo, você tem que lembrar 🙂  E digite :

sudo dpkg -i w32codecs_20071007-0.1_i386.deb

Onde 20071007-0.1_i386 é minha versão de download você poderá ter uma versão diferente e provavelmente mais recente.

Feito isso acredito que já podemos testar.

vlc url_do_video/nome_do_video.wmv.

Bom Filme !!

Tags: , , , ,

Flash – Jogos OnLine

Para descontrair um pouco vou postar um site com joguinhos on line em flash, não é preciso instalar o jogo na máquina, mas é necessário ter o flash player instalado no navegador.

Eu aconselho que seu navegador seja o opera ou se preferir pode ser o firefox

Então vamos ao Joguinho que é fazer um trail pelos obstaculos mas diversos. É muito divertido.


Trail

Espero que gostem pois a vida tem que ter diversão também

Tags: , ,

Wifi em linha de comando

O ubuntu tem inúmeros programas para fazer a conexão wifi em notebooks. Mas eu queria saber como fazer na mão em linha de comando.

Após  procurar um pouco na Internet, ou seja no google consegui algumas informações que vou passar aqui no blog.
Em primeiro lugar vamos encontrar as redes disponiveis para conexão. Inclusive as dos vizinhos então usem com moderação esta dica.

Digite :

iwlist scan

Neste momento será retornado as redes disponiveis.
Exemplo de saida do programa iwlist:

lo        Interface doesn't support scanning.

eth0      Interface doesn't support scanning.

eth1      Scan completed :
Cell 01 - Address: 00:30:65:05:E6:04
ESSID:"minha_rede"
Protocol:IEEE 802.11b
Mode:Master
Channel:1
Frequency:2.412 GHz (Channel 1)
Encryption key:on
Bit Rates:1 Mb/s; 2 Mb/s; 5.5 Mb/s; 11 Mb/s
Quality=64/100  Signal level=-62 dBm
Extra: Last beacon: 4156ms ago

Explicando a interface lo é a da própria máquina, a interface eth0 é da rede cabeada e não poderá ser feito o scan de redes sem fio por ela. A que realmente importa é a eth1 pois é minha rede sem fios.
Foi encontrada a rede de nome minha_rede e existem uma senha habilitada para a mesma.
Agora que a rede foi detectada vamos ao passo dois que é associar ela a sua interface, neste momento você vai precisar da senha de administrador do computador.

Digite:

sudo iwconfig eth1 essid "minha_rede" key s:sua_senha_da_rede

Neste momento você esta fazendo a associação da rede “minha_rede” a sua interface de rede eth1 utilizando uma senha baseada em ASCII sua_senha_da_rede que contem 12 caracteres.

Algumas observações até esse ponto. No meu caso minha interface de rede ligada é a eth1, mas podem ser outros dependendo do fabricante. Poderiam ser também wlan0, ath0 dentre outras.
Segundo ponto é que minha rede utiliza senha para acesso, essa senha é baseada em ASCII mas não é um padrão podem haver outros.

Agora para finalizar caso sua máquina trabalhe com DHCP (ip dinâmico) você terá de conseguir seu ip novo com um comando.

Digite:

sudo dhclient eth1

Neste momento você receberá um ip e já pode se conectar a rede local e caso essa rede tenha acesso a internet pode navegar.

Para maiores informações e eu aconselho que seja feito a leitura do manual 🙂

Digite:

man iwconfig

Obrigado Joe Rabelo pelos testes na sua máquina.

Tags: , , , ,

tar e rm alguns segredos…

Hoje vamos falar um pouco sobre backup e sobre uma curiosidade do comando rm.
Eu precisa criar um pacote compactado com os arquivos fontes de um aplicativo da empresa onde trabalho. Mas neste pacote não poderiam ir os arquivos de trabalho do sistema como PDF, Imagens, XML e etc.
Para fazer a compactação geramente utilizo o tar pois ele é de simples entendimento e largamente utilizado por pessoas que utilizam UNIX.
A sintaxe básica é:

tar  arquivo_saida arquivo_entrada1 arquivo_entrada_n

Assim como utilizei a flag –exclude no rsync posso utilizar no tar também.
Então para resolver meu problema foi simples digitei.

tar -vczf arquivosFontes.tar.gz /home/valdinei/ --exclude /home/valdinei/userFiles

Onde as opções são definidas da seguinte forma:

-v mostrar as saidas na tela
-c criação de arquivo
-z tipo de compactação
-f arquivo

Resolvido o problema com este comando, mas fazendo os testes para descobrir como o comando funcionava foram sendo criados arquivo lixo em meu ambiente de teste. Este arquivos eram os –exclude, –exclude= e coisas do tipo pois fiz muitas tentativas 🙂

Para apagarmos apagarmos arquivos é so utilizar o comando rm <arquivo>, sendo este um arquivo com um nome normal.
Neste caso meu arquivo não tinha um nome normal.

Digite no seu console

touch --test.

Depois

 rm --test

para ver o que acontece…. nada vai dar um erro.

Tem um explicação logica para isso, quando chamamos um comando é utlizado uma nova shell para executa-la e como o sinal (–) é utlizado para a passagem de paramentros da um erro pois agora este sinal pertence ao nome do arquivo.

Sem se extender mais sobre o assunto vamos a solução:

rm -- --test

Pronto apagamos o arquivo. Porque?
Bem agora definimos que o comando vai ser executado pelo shell que estamos utilizando.

Espero ter ajudado pois isso me salvou hoje criando um arquivo limpo e deixando minha máquina sem arquivos com nomes bizarros.

Abraços
Dinei.

Tags: , , , , ,