Uma pincelada no GIT
- publicado em 05 de janeiro de 2010
O git é um programa para controle de versões. O que mais me agrada nele é a sua flexibilidade e a sua simplicidade de uso. O que segue aí é só uma amostra do que o git pode fazer por você. Para mais informações visite http://git-scm.com/
Apresentando-se ao git
O que faremos aqui é versionar um projeto que já temos. Neste exemplo meu projeto estará em /home/juca/src/novo_projeto. Então, vamos lá! Depois de instalado o git (instruções de instalação aqui) a primeira coisa a fazer, é apresentar-se ao git. Para tanto, vamos informar ao git nosso nome e email.
$ git-config --global user.name "Juca"
$ git-config --global user.email "juca@minhacasa.nada"
Versionando nosso primeiro projeto
Agora que já nos apresentamos ao git, vamos versionar nosso projeto. A primeira coisa é ir até o diretório onde está seu projeto, depois dar um «git init» neste diretório para criar um novo repositório do git, e por fim, adicionar e “commitar” os arquivos do projeto. A coisa fica assim:
$ cd /home/juca/src/novo_projeto
$ git init Initialized empty Git repository in /home/juca/src/novo_projeto/.git/
$ git add .
$ git commit
Com o que fizemos até agora, já temos o projeto versionado. Para ver o log dos commits use «git log», assim:
$ git log
commit dc00b38b6beb9db50d8b0ad0fb7e6a80689c80cb
Author: Juca
Date: Tue Jan 5 12:41:51 2010 -0200
Primeiro commit do tutorial
Podemos também listar os arquivos que estão sob o controle de versão usando «git ls-files», assim:
$ git ls-files arquivo1 arquivo2
Alterando e trabalhando com os arquivos do projeto
Agora, vamos alterar um arquivo pra ver como fica.
$ emacs arquivo1
Altere o que quiser e salve o arquivo. Antes de adicionar e commitar podemos ver o que foi alterado com «git diff»:
$ git diff --color arquivo1
diff --git a/arquivo1 b/arquivo1
index a353720..d80b33a 100644
--- a/arquivo1 +++ b/arquivo1
@@ -1 +1,2 @@ -Oi, eu sou o arquivo1. Essa merda é só pra brincar com o git e escrever o tuto... \ No newline at end of file +Oi, eu sou o arquivo1 (agora alterado). +Essa merda é só pra brincar com o git e escrever o tuto... \ No newline at end of file arquivo1
Obs: A opção «–color» é usada para que o resuldado do diff fique colorido, mas aqui no tuto as cores foram pro saco… Agora, é só adicionar e commitar o arquivo modificado. $ git add arquivo1 $ git commit
Criando branches
Agora vamos falar de branches. Branches não custam nada no git, e são muito fáceis de manejar. Todo novo repositório do git é criado com um branch chamado «master». Tudo o que fizemos até agora foi neste branch. Vamos criar um novo agora com «git branch»
$ git branch # primeiro para ver os branchs que já existem
* master
$ git branch teste #criando o branch 'teste'
$ git checkout teste #mudando para o branch 'teste'
Agora, vamos alterar um arquivo no branch teste.
$ emacs arquivo1
Altere e salve o arquivo. Em seguida, adicione e commite o arquivo modificado
$ git add arquivo1
$ git commit
Neste ponto, temos arquivos que têm diferenças entre a versão do branch master e do branch teste. Para «juntar» as versões dos dois branches usaremos «git merge». O que faremos é o seguinte: Primeiro voltaremos ao branch master e depois faremos o merge das versões. git checkout master git merge teste Agora, depois do merge, você pode ver que as alterações feitas no branch teste também estão visíveis no branch master. Sendo assim, podemos apagar o branch teste
$ git branch -D teste
Trabalhando com os outros
Bom, até agora foi o basicão do «eu trabalhando comigo mesmo», mas a graça da coisa é distribuir o código e desenvolver com os outros, não? Então! agora vamos ver como usar o git para distribuir (ou receber de outros) o código.
Clonando um projeto
Vamos supor que eu (Juca) estou em hostjuca e um outro cara (Zé) está em hostze e quer contribuir com o projeto. Para fazer isto, o git pode usar ssh ou http. Vamos começar pelo ssh é qué mais simples. O Zé precisa ter acesso liberado no ssh da minha máquina. hostjuca será o repositório «principal» O Zé ainda não tem uma cópia do projeto, então a primeira coisa a fazer é clonar o projeto com «git clone». A sintaxe do «git clone» é assim (lembrando que estamos usando ssh):
git clone ssh://[usuario@]host:[porta]/caminho/pro/repositorio
Então, pro Zé clonar meu projeto, a coisa ficaria assim:
ze@hostze:~/src$ git clone ssh://ze@hostjuca:22/home/juca/src/novo_projeto
Initialized empty Git repository in /home/ze/src/novo_projeto/.git/
ze@hostjuca\'s password:
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 7 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (7/7), done.
Agora o Zé já tem os arquivos do meu projeto e pode brincar a vontade.
ze@hostze:~/src$ cd novo_projeto
ze@hostze:~/src/novo_projeto$ vi arquivo2 #O Zé é filho do capeta, vocês viram, né?
ze@hostze:~/src/novo_projeto$ git add arquivo2
ze@hostze:~/src/novo_projeto$ git commit
Sincronizando os repositórios
Agora as versões do Juca e do Zé estão diferentes. Temos duas opções para sincronizar estas duas versões. Ou o Juca “puxa” as mundaças do Zé ou o Zé empurra as mudanças dele para o repositório do Juca. Antes de prosseguirmos, vale uma explicaçãozinha sobre o comportamento do git. O git não gosta que você empurre o mesmo branch que você clonou (ou puxou). Parece estranho, mas tem sentido. Tente empurrar o branch master que você verá um aviso muito explicativo.
Empurrando as coisas
Como o Zé já tem acesso a máquina do Juca, vamos deixá-lo empurrar as mudanças para o repositório principal. Isso será feito com «git push». A sintaxe do «git push» é a seguinte:
git push ssh://[usuario@]host:[porta]/caminho/pro/repo branch_local
Por causa do comportamento do git, o Zé tem que primeiro criar um novo branch e empurrar este novo branch. A coisa fica assim:
ze@hostze:~/src/novo_projeto$ git branch branchdoze
ze@hostze:~/src/novo_projeto$ git push ssh://ze@hostjuca:22/home/juca/src/novo_projeto branchdoze
ze@hostjuca\'s password:
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 349 bytes, done.
Total 3 (delta 0), reused 0 (delta 0) To ssh://ze@hostjuca:22/home/juca/src/novo_projeto
* [new branch] branchdoze -> branchdoze
Com isso, lá no repositório principal (hostjuca) foi criando um branch chamado branchdoze, e para terminar a operação o Juca (dono do repositório principal) precisa fazer um “merge” do branch “branchdoze” para o branch “master”.
juca@hostjuca:~/src/novo_projeto$ git merge branchdoze
Com isso temos o código que está em hostze e o código que está em hostjuca (o repo principal) sincronizados.
Voltando no tempo…
Lembra que falei que tinhamos duas opções pra sincronizar o código: empurrar ou puxar? Então, o que fizemos até aqui foi empurrar o código de um desenvolvedor para o repositório principal. Vamos fazer o contrário (o repo principal puxa as alterações do dev) só pra ver como fica. Pra isso, vamos voltar o código do repositório principal para a versão anterior as mudanças feitas pelo Zé lá em hostze. Isso é feito com «git reset». A sintaxe é a seguinte:
$ git reset --hard <commit>
Então, será feito o seguitne no repositório principal: primeiro daremos um «git log» pra ver qual o hash do commit que queremos e depois usaremos o git reset para voltar para esta versão. Assim:
juca@hostjuca:~/src/novo_projeto$ git log
commit 2117cfdf7a4ff0683487a33008e3fc5bca42cdbe
Author: Zé Date: Tue Jan 5 15:49:24 2010 -0200
Primeira alteração do Zé
commit 937f17e96ee04e1221783e664d270dda5d87657d
Author: Juca Date: Tue Jan 5 14:37:20 2010 -0200
Só testando o novo branch
commit dc00b38b6beb9db50d8b0ad0fb7e6a80689c80cb
Author: Juca Date: Tue Jan 5 12:41:51 2010 -0200
Primeiro commit do tutorial
juca@hostjuca:~/src/novo_projeto$ git reset --hard 937f17e96ee04e1221783e664d270dda5d87657d
HEAD is now at 937f17e Só testando o novo branch
Com isso temos o nosso repositório principal de volta a época em que o Zé não tinha alterado nada.
Puxando as coisas
Agora vamos sincronizar fazendo com que o repositório principal “puxe” as mudanças do repositório do Zé. Isso será feito com «git pull». A sintaxe é a seginte:
$ git pull ssh://[usuario@]host:[porta] branch_remoto
Então, pro Juca puxar as mudanças do Zé, a coisa fica assim:
juca@hostjuca:~/src/novo_projeto$ git pull ssh://juca@hostze:22/home/ze/src/novo_projeto master
juca@hostze\'s password:
From ssh://hostze:22/home/ze/src/novo_projeto
* branch master -> FETCH_HEAD
Updating 937f17e..2117cfd
Fast forward arquivo2 | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
Como não existia nenhum conflito entre as versões, tudo ocorreu tranqüilamente, e já temos novamente nossos códigos em hostze e hostjuca sincronizados. Bom, isso é só uma amostra do que o git pode fazer, mas o git pode fazer muito mais que isso. Dá uma olhadinha no gitmagic pra você ver. Na minha próxima postagem sobre o git, explico como configurar o git para usar http ao invés de ssh. Então, até lá e divirtam-se!
Criando um túnel reverso com SSH
- publicado em 22 de dezembro de 2009
Essa aqui é uma rapidinha sobre como criar um túnel reverso no ssh. Pergunta: Pra que serve um túnel ssh reverso? Resposta: Eu uso isso pra chegar em uma máquina que não poderia chegar diretamente (máquina atrás de nat e talz…) Vamos lá!
Suponhamos que eu tenha dois hosts distintos (host1 e host2). host1 está atrás do nat e host2 está conectado diretamente na internet. O que faremos aqui é abrir uma conexão ssh de host1 para host2 e deixar o túnel aberto, assim podendo ir de host2 para host1 (adeus nat!). A sintaxe para sair de host1 para host2, deixando o túnel aberto, seria assim:
ssh -R [porta_pra_voltar_pra_host1]:localhost:[porta_ssh_host2] host2
Então, eu estando em host1 faria o seguinte:
juca@host1:~$ ssh -R 2222:localhost:22 host2
Ai, enquanto (e somente enquanto) esta conexão estiver aberta, é possivel conectar de host2 em host1 usando: ssh -p [porta_pra_voltar_pra_host1] localhost Então, eu estando em host2, faria o seguite:
juca@host2:~$ ssh -p 2222 localhost Bom... É isso ai. Molezinha, não?
Instalação e configuração do PostgreSQL no Debian
- publicado em 21 de dezembro de 2009
Essa aqui é uma rapidinha sobre como instalar e configurar o PostgreSQL no Debian.
Primeiro, instalar o banco:
# aptitude install postgresql
Depois de baixar e instalar é hora de configurar. O usário root do nosso banco de dados é o postgres. No processo de instalação foi criado um usuário chamdo postgres também no sistema. Então, nos logaremos com este usuário.
# su postgres
Por padrão, o usuário de banco de dados “postgres” não tem senha, então agora nos logaremos no shell do PostgreSQL para alterar a senha do usuário postgres.
Primeiro, logando no shell…
$ psql
Agora, já no shell do PostgreSQL, vamos alterar a senha do usuário postgres
postgres=# ALTER USER postgres WITH PASSWORD 'qualquersenha';
Esse cara que a gente acabou de configurar ai é o root do banco de dados… A gente não vai ficar usando esse usuário nas nossas aplicações, né? Então! vamos criar um novo usuário.
postgres=# CREATE USER usuario NOCREATEDB NOSUPERUSER NOCREATEROLE PASSWORD 'senha';
Agora, vamos criar uma tabela também
postgres=# CREATE DATABASE minhabase;
Bom, já criamos usário, base de dados… Agora precisamos configurar o modo como os clientes se autenticarão no servidor. Essas configurações se encontram no arquivo pg_hba.conf, que no Debian fica em /etc/postgresql/8.4/main.
OBS: Esse 8.4 aí em cima se refere à versão que estou usando. Se sua versão for diferente, o número também será. Vamos abrir o arquivo e editá-lo.
Como o arquivo é bem comentado não vou me alongar na explicação… Qualquer coisa é só olhar aqui. A primeira coisa que farei aqui é deixar o tipo de autenticação para os usuários locais como md5.
Então, a linha que era assim: local all all ident Ficou assim: local all all md5
Do jeito que as coisas estão, somente usuários locais poderão se conectar ao banco. Então agora vamos fazer umas configurações para que clientes remotos possam se conectar ao banco. O primeiro passo para liberar conexões para clientes remotos é adicionar uma liniha ao pg_hba.conf. A linha seria algo como: host all all 0.0.0.0/0 md5.
Pra finalizar precisaremos também editar o arquivo postgresql.conf, que fica no mesmo diretório que o pg_hba.conf.
No postgresql.conf procure pela linha #listen_addresses = “localhost” e mude para listen_addresses = “*”
Agora é só reiniciar o postgresql…
/etc/init.d/postgresql-8.4 restart
E está tudo pronto!
Pequena introdução ao sqlalchemy
- publicado em 07 de dezembro de 2009
#!/usr/bin/env python
#-*- coding: utf-8 -*-
# Este documento é uma rápida introdução ao SQLAlchemy.
#
# SQLAlchemy is the Python SQL toolkit and Object Relational Mapper
# that gives application developers the full power and flexibility of SQL.
#
# It provides a full suite of well known enterprise-level persistence patterns,
# designed for efficient and high-performing database access, adapted into a
# simple and Pythonic domain language.
#
# Ao escrever isso estou usando python 2.6 e sqlalchemy 0.5.5.
# Como exemplo vou organizar a coleção de discos.
m = raw_input("Mostrar sql gerado?[s/n] ")
mostrar = [True, False][m.lower() == 'n']
espera = mostrar
############# PASSO 1 - CRIAR UMA CONEXÃO COM O BANCO DE DADOS. ################
# O banco de dados usado será o sqlite.
# O sqlalchemy usa um objeto 'engine' para se conectar ao banco de dados.
from sqlalchemy import create_engine
#O parametro 'echo = True' faz com que o sql gerado seja mostrado na tela.
engine = create_engine('sqlite:///discoteca.db', echo = mostrar)
########### PASSO 2 - CRIAR AS TABELAS QUE SERÃO USADAS. #######################
#Uma tabela no sqlalchemy é um objeto do tipo Table.
#objetos do tipo Column são usados para definir os campos da tabela.
from sqlalchemy import Table, Column, Integer, String, ForeignKey, MetaData
# MetaData é o objeto responsável pelas queries e orm.
metadata = MetaData()
tabela_bandas = Table('bandas', metadata,
Column('id', Integer, primary_key = True),
Column('nome', String),
Column('lugar', String)
)
#Um disco pode ter mais de uma banda.
tabela_discos = Table('discos', metadata,
Column('id', Integer, primary_key = True),
Column('nome', String),
Column('ano', Integer)
)
tabela_discos_bandas = Table('discos_bandas', metadata,
Column('id', Integer, primary_key = True),
Column('id_banda', Integer, ForeignKey('bandas.id')),
Column('id_disco', Integer, ForeignKey('discos.id')),
)
#Neste exemplo uma música só está em um único disco.
tabela_musicas = Table('musicas', metadata,
Column('id', Integer, primary_key = True),
Column('id_disco', Integer, ForeignKey('discos.id')),
Column('id_banda', Integer, ForeignKey('bandas.id')),
Column('numero', Integer),
Column('nome', String)
)
#Como as tabelas não existem, as criaremos usando a nossa instância de MetaData().
#Nossa engine (criada no passo 1) será passada como parametro.
metadata.create_all(engine)
if espera:
raw_input("\nO SQL gerado foi a criação das tabelas.")
# Conexão com o banco de dados estabelecida, tabelas criadas...
#Agora é hora de definir nossos objetos.
####### PASSO 3 - CRIAR AS CLASSES E MAPEÁ-LAS COM AS TABELAS CRIADAS. #########
#Para mapear as classes com as tabelas usaremos o método mapper()
#A sintaxe do mapper é a seginte: mapper(classe, tabela).
#Com isso, associa-se a classe à tabela.
from sqlalchemy.orm import mapper, relation
class musica(object):
def __repr__(self):
numero = self.numero or 0
nome = self.nome or ''
if self.disco:
disco = self.disco.nome
else:
disco = ''
return """numero: %i, nome: %s, disco: %s""" %(numero, nome, disco)
#mapeando musica com tabela_musicas.
mapper(musica, tabela_musicas)
class banda(object):
def __repr__(self):
nome = self.nome or ''
lugar = self.lugar or ''
return """nome: %s, lugar: %s""" %(nome, lugar)
#mapeando banda com tabela_bandas.
#Definiremos também a relação banda/musica usando relation(),
#'backref' cria a relação também 'do lado contrário'.
#O parâmetro 'properties' cria atributos para a classe que está sendo mapeada.
mapper(banda, tabela_bandas,
properties = {'musicas' : relation(musica, backref = 'banda')}
)
class disco(object):
def __repr__(self):
nome = self.nome or ''
ano = self.ano or 0
if self.bandas:
banda = ','.join([i.nome for i in self.bandas])
else:
banda = ''
return """nome: %s, ano: %s, banda: %s""" %(nome, str(ano), banda)
#Mapeando disco com tabela_discos, onde definiremos também relacionamentos.
#A relação bandas/discos é muitos-para-muitos. Por isso foi passado o parâmetro
#'secondary'.
mapper(disco, tabela_discos,
properties = {'musicas' : relation(musica, backref = 'disco'),
'bandas' : relation(banda,
secondary = tabela_discos_bandas,
backref = 'discos')
}
)
#Já está tudo criado, os objetos mapeados... Vamos brincar com a coisa!
###################### BRINCANDO COM OS NOSSOS OBJETOS ########################
#Primeiro instanciar banda() e cadastrar uma nova banda.
#Repare que os atributos do objeto são as colunas da tabela (da hora, né!) .
nova_banda = banda()
nova_banda.nome = "Tankard"
nova_banda.lugar = "Frankfurt"
#Bom, uma nova banda foi criada aí, mas ainda não foi salva no banco.
#Para salvar no banco usaremos um objeto 'session' que será criado com sessionmaker
#Nossa 'session' será associada à nossa 'engine'.
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
#Agora, com a session criada, é só adicionar nosso objeto a session...
session.add(nova_banda)
# ...e 'commitar' a coisa.
session.commit()
if espera:
raw_input("\nEste sql é da inserção de uma banda.")
#Pronto, objeto salvo. Agora vamos recuperá-lo.
#Usaremos o método session.query() para fazer isso.
uma_banda = session.query(banda).filter(banda.nome == "Tankard").first()
if espera:
raw_input("\nEste aqui é a recuperação de uma banda.")
#Bom, vamos criar um disco.
novo_disco = disco()
novo_disco.nome = "The Morning After"
novo_disco.ano = 1988
session.add(novo_disco)
session.commit()
#Um disco tem músicas, não?
musicas = ['Intro', 'Commandment', 'Shit-faced', 'TV Hero', 'F.U.N.',
'Try Again', 'The Morning After', 'Desperation',
'Feed the Lohocla', 'Help Yourself', 'Mon Cheri', 'Outro']
i = 1
for m in musicas:
nova_musica = musica()
nova_musica.nome = m
nova_musica.banda = uma_banda
nova_musica.numero = i
i += 1
#Lembra do relation(), backref e tal que falei lá em cima? Então, olha aí!
#O atributo nova_musica.disco aí embaixo foi criado com eles.
nova_musica.disco = novo_disco
session.add(nova_musica)
session.commit()
#Usando novamente um atributo criado na configuração do mapper...
uma_banda.discos.append(novo_disco)
#Bom, vamos cadastrar mais umas coisas aí pra entender direitinho como funciona.
rdp = banda()
rdp.nome = u"Ratos de Porão"
rdp.lugar = u"São Paulo"
cl = banda()
cl.nome = u"Cólera"
cl.lugar = u"São Paulo"
pk = banda()
pk.nome = u"Psykóze"
pk.lugar = u"São Paulo"
fc = banda()
fc.nome = u"Fogo Cruzado"
fc.lugar = u"São Paulo"
outro_disco = disco()
outro_disco.nome = "Sub"
outro_disco.bandas.append(rdp)
outro_disco.bandas.append(cl)
outro_disco.bandas.append(pk)
outro_disco.bandas.append(fc)
session.add(outro_disco)
#session.commit()
musicas_sub = [(u'Parasita', rdp), (u'Vida Ruim', rdp), (u"Poluição Atômica", rdp),
(u"X.O.T.", cl), (u"Bloqueio Mental", cl),
(u"Quanto Vale a Liberdade", cl), (u"Terceira Guerra Mundial", pk),
(u"Buracos Suburbanos", pk), (u"Fim do Mundo", pk),
(u"Desemprego", fc), (u"União entre os Punks do Brasil", fc),
(u"Delinqüentes", fc), (u"Não Podemos Falar", rdp),
(u"Realidades da Guerra", rdp), (u"Porquê?", rdp), (u"Histeria", cl),
(u"Zero zero", cl), (u"Sub-ratos", cl), (u"Vítimas da Guerra", pk),
(u"Alienação do Homem", pk), (u"Desilusão", pk), (u"Inimizade", fc),
(u"Punk Inglês", fc), (u"Terceira Guerra", fc)]
i = 1
for m in musicas_sub:
nova_musica = musica()
nova_musica.nome = m[0]
nova_musica.banda = m[1]
nova_musica.numero = i
session.add(nova_musica)
session.commit()
nova_musica.disco = outro_disco
i += 1
#Agora que já criamos as paradas, vamos ver...
bandas = session.query(banda).all()
for b in bandas:
print "Banda: " , b.nome
for d in b.discos:
print " Disco: ", d.nome
for m in d.musicas:
if m.banda.id == b.id:
print " Música: ", m.nome
Python + Oracle
- publicado em 26 de novembro de 2009
Aqui no trampo o pessoal usa banco de dados Oracle. E sempre preciso fazer alguns scripts em Python pra trabalhar com o Oracle. Então aqui vai uma rapidinha sobre conectar no Oracle usando Python.
Primeiro você precisa instalar o oracle client (instalação fora do escopo do post… STFW). Depois do client instalado, é preciso instalar o módulo cx_Oracle (está aqui), para conectar no banco através do Python.
Depois do módulo instalado a coisa fica fácil fácil.
>>> import cx_Oracle
>>> ora_conn = cx_Oracle.connect(user, passwd, host/service_name)
>>> ora_cur = ora_conn.cursor()
>>> ora_cur.execute("SELECT * FROM DUAL")
>>> resultado = ora_cur.fechall()
>>> ora_conn.close()
Fácil, né?
Resolvendo problema
Se na hora do import ocorrer um erro assim:
>>> import cx_Oracle
Traceback (most recent call last): File "", line 1, in File "build/bdist.linux-i686/egg/cx_Oracle.py", line 7, in File "build/bdist.linux-i686/egg/cx_Oracle.py", line 6, in __bootstrap__ ImportError: libclntsh.so.10.1: cannot open shared object file: No such file or directory
>>>
O problema é que o oracle não está no PATH do seu sistema. Para resolver isto, no bash, eu uso:
$ export ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server/
$ export LD_LIBRARY_PATH=$ORACLE_HOME/lib
$ export PATH=$ORACLE_HOME/bin:$PATH
Bom, é isso aí… Mamão-com-açucar!
Alterar tamanho padrão do terminal no Gnome
- publicado em 20 de agosto de 2009
emacs /usr/share/vte/termcap/xterm
alterar: :co#158:it#8:li#46:
Reiniciar o X.
Instalar Debian a partir de outro unix-like com debootstrap
- publicado em 19 de agosto de 2009
Este documento mostra como instalar um sistema Debian from scratch a partir de outro sistema operacional unix-like usando o debootstrap. A primeira coisa a fazer é baixar o debootstrap.
Bootstrap a basic Debian system debootstrap is used to create a Debian base system from scratch, without requiring the availability of dpkg or apt. It does this by downloading .deb files from a mirror site, and carefully unpacking them into a directory which can eventually be chrooted into.
Aqui você encontra o debootstrap para baixar.
# cd /usr/local/src
# wget -c http://ftp.debian.org/debian/pool/main/d/debootstrap/debootstrap_1.0.15_all.deb
Depois de baixar é a vez de descompactar e instalar.
# ar -x debootstrap_1.0.15_all.deb
# cd / # zcat /usr/local/data.tar.gz | tar xv
Agora já com o debootstrap instalado podemos começar a instalação do nosso Debian novo. Para seguir em frente é necessário que já se tenha uma partição criada e montada para o novo sistema. A partição que usarei neste caso é identificada como /dev/sda1 e está montada em /mnt. A sintaxe básica do debootstrap é: debootstrap –arch <arquitetura> <distribuição> <diretório alvo> <repositório>. Com isto será instalado um sistema mínimo no diretório alvo indicado
# /usr/sbin/debootstrap --arch amd64 squeeze /mnt http://ftp.br.debian.org/debian
Com o sistema básico instalado é hora de dar um chroot para o novo sistema. Mas antes disso, vamos montar algumas coisas necessárias.
# mount -o bind -t proc /proc /mnt/proc
# mount -o bind /dev /mnt/dev
# mount -o bind /dev/pts /mnt/dev/pts
# mount -o bind /sys /mnt/sys
E agora sim, dar o chroot para o novo sistema:
# LANG=C chroot /mnt
Agora que já estamos dentro do novo sistema vamos configurá-lo
A primeira coisa a configurar é o debconf e deixá-lo com prioridade baixa (maníaco é foda…)
# dpkg-reconfigure debconf
Agora ajustando o horário:
# dpkg-reconfigure tzdata
Agora vamos configurar o apt.
# nano /etc/apt/sources.list
Eu acrescentei os seguintes repositórios:
deb-src http://ftp.br.debian.org/debian/ testing main
deb http://security.debian.org/ testing/updates main
deb-src http://security.debian.org/ testing/updates main
Depois de adicionar os novos repositórios, recarregar as informações de pacotes:
# aptitude update
Agora vamos configurar teclado e idioma. Para isto instalaremos os pacotes locales e console-data
# aptitude install locales console-data
Ainda nos falta um kernel… Vamos a ele! Procure pelo kernel mais adequado para você:
# aptitude search linux-image
E depois de achar seu kernel, instale-o:
# aptitude install linux-image-2.6.30-1-amd64
Vamos configurar também o fstab.
#Raiz em /dev/sda1 UUID=f2f94e87-327f-4948-88ef-0338bb23848e / ext4 relatime,errors=remount-ro 0 1
# swap em /dev/sda2 UUID=71c38be9-a1b4-4f45-82b3-c04bdeba533d none swap sw 0 0
Depois de configurar o fstab, vamos montar tudo.
# mount -a
Para iniciar o nosso novo sistema precisamos de um bootloader. Você pode usar o bootloader que você já usa no seu outro sistema operacional ou instalar um novo. Para instalar um bootloader novo você usa:
# aptitude install grub
Mas no caso deste exemplo, vou usar o grub já existente da outra distro. Seguem as linhas adicionadas ao arquivo de configuração do grub.
title Debian uuid f2f94e87-327f-4948-88ef-0338bb23848e kernel /boot/vmlinuz-2.6.30-1-amd64 root=UUID=f2f94e87-327f-4948-88ef-0338bb23848e ro quiet splash initrd /boot/initrd.img-2.6.30-1-amd64
Agora já estamos quase no fim. Mas antes, vou instalar uns pacotes que eu uso: pppoeconf para configurar a rede depois do reboot, emacs que é minha ferramenta de trabalho e usplash porque eu gosto, oras!
# aptitude install emacs23-nox pppoeconf usplash
Os pacotes que preciso já estão instalados, então agora é só configurar os usuários. Primeiro configurar a senha de root e depois adicionar um usuário comum pra mim.
# passwd
# adduser juca
Agora tudo pronto! Já temos um Debian novinho em folha. Desmonte tudo o que foi montado, reinicie a máquina, escolha o Debian no seu bootloader e… Divirta-se!