CVS - Slides Parte 2 - Administração

  • 693 views
Uploaded on

 

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
693
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
6
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • Neste módulo apresentaremos as tarefas relacionadas à administração do CVS. O foco desde módulo é o papel do administrador de sistemas, o profissional que prepara o ambiente para o uso do CVS (instalando, configurando permissões, criando repositórios, liberando acessos e gerenciando back-ups). Começaremos pelo dimensionamento de capacidade para a implantação do CVS. Veremos então o que deve ser levado em conta na escolha da distribuição do CVS a ser utilizada. Instalaremos o CVS na prática e criaremos repositórios; veremos então um pouco mais sobre como funciona um repositório CVS. Criaremos e importaremos projetos para o CVS. Veremos como realizar tarefas de rotina, como back-ups, movimentações e remoções de repositórios. Passaremos à configuração da segurança do repositório: como estabelecer protocolos de autenticação, controlar permissões, etc. Fecharemos conhecendo os arquivos e as variáveis de ambiente que controlam o comportamento do CVS.
  • Este slide mostra nossa agenda para este módulo do treinamento, voltado para a administração do CVS.
  • Acredito que, neste ponto, todos os presentes ao treinamento pretende implantar o CVS como sistema de controle de versões em suas respectivas empresas ou grupos de trabalho. A primeira preocupação de vocês deve ser implantar uma solução que funcione bem e atenda as necessidades dos usuários. Portanto, ninguém ficará satisfeito se implantar um sistema que fique fora do ar, seja demasiado lento ou que, por outro lado, desperdice recursos e acabe saindo caro. Como vimos, o CVS é um software open-source e pode ser usado sem custos de licenças, mas hardware é pago e caro. Portanto, de nada adianta usar um software sem custo se os recursos que ele consumir forem super-dimensionados e caros. O propósito desta seção do treinamento é dar o caminho das pedras para se fazer um planejamento de capacidade adequado para uma implantação do CVS. Lançamos mão de alguns conhecimentos com projetos de longa duração que utilizaram com sucesso o CVS e de alguns experimentos para apresentar aqui métricas que auxiliarão nas estimativas de consumo de recursos. Como o CVS é um tradicional sistema cliente/servidor, o natural é pensarmos em dimensionar ambos os lados, sem nos esquecer da comunicação entre eles. Desde já, porém, podemos deixar de lado o dimensionamento do cliente. Por ser muito leve, não demandar praticamente nenhum espaço para instalação e, muitas vezes, já estar embutido na IDE (ambiente gráfico) do programador, o cliente não precisa ser considerado no planejamento. Resta-nos o planejamento do servidor (com a rede), que fica resumido a 4 aspectos: armazenamento (espaço em disco), rede (banda passante), memória (RAM) e processamento. O armazenamento é, de longe, o aspecto mais importante a ser considerado. A rede vem logo em seguida, pois pode dar grandes dores de cabeça ao administrador do CVS. Já memória e processamento quase nunca serão problemas. Veremos a seguir como quantificar cada um desses aspectos.
  • O armazenamento é o aspecto mais crítico do planejamento de capacidade do CVS. Posto de forma simples, estimar o espaço em disco consumido pelo CVS equivale a estimar o tamanho do seu repositório o que, por sua vez, é o mesmo que estimar o tamanho dos históricos de todos os arquivos sob o controle do CVS. Notem que precisamos estimar o tamanho dos históricos, não dos arquivos em si! Existem 3 fatores que influenciam os tamanhos dos históricos e, logo, nossa estimativa de espaço: o tamanho dos arquivos (o fator mais óbvio), a freqüência de alteração dos arquivos (também intuitivo, pois cada revisão precisa ser armazenada) e o tipo dos arquivos, isto é, texto ou binário (este é o fator menos claro). Para entender melhor como esse fatores influenciam o tamanho do repositório, vamos nos recordar do que falamos sobre a forma como o CVS organiza seus arquivos de histórico. Os históricos de arquivos de texto guardam apenas as diferenças (deltas) entre as revisões. Já para arquivos binários, não há como armazenar diferenças, logo, o CVS mantém cada revisão integralmente nos arquivos de histórico. Como arquivos binários já são naturalmente maiores que arquivos texto, não precisamos pensar muito para concluir que eles são os grandes vilões do repositório. Para nossa sorte, grande parte dos arquivos binários com os quais lidamos são gerados a partir de fontes de texto: o caso mais típico são os executáveis e as bibliotecas compiladas. Como vimos no início do treinamento, esse tipo de arquivo não deve ser mantido sob o controle de versões, desde que possam ser gerados de forma simples e rápida.
  • O aspecto mais óbvio influenciando o consumo de espaço do repositório é o tamanho dos arquivos em si. Quanto maiores os arquivos, mais informações devem ser mantidas nos históricos e, logo, maior o tamanho total do repositório. Entretanto, os históricos não crescem em velocidade constante. No início do projeto, os arquivos mudam e crescem de forma bem mais rápida, pois é quando o código está surgindo. Isso faz com que os históricos cresçam a uma velocidade alta. À medida que o projeto vai sendo finalizado, os arquivos vão atingindo uma estabilidade e passam a mudar menos e seu tamanho fica praticamente constante. A maioria das alterações são correções de defeitos, ou novos requisitos. Com isso, a velocidade de crescimento dos históricos diminui. Muitos arquivos páram de sofrer alterações, deixando alguns históricos com tamanho constante. Uma função que modela bem o crescimento dos históricos ao longo do tempo é a função logaritmo. Ela cresce mais rapidamente no início e chega a um ponto onde praticamente não cresce mais. Certamente, ela deve ser parametrizada de acordo com o arquivo e com projeto. Os fatores que influenciam já foram vistos: tamanho, freqüência de modificações e tipo do arquivo. No próximo slide vemos 3 arquivos diferentes, cada um com características próprias, cujos históricos crescem em velocidades diferentes. Ainda assim, as 3 curvas encaixam-se na função logaritmo. A função nos ajuda a visualizar o crescimento dos históricos, mas precisamos de uma resposta para a pergunta: como estimar o tamanho de “estabilidade” do histórico de um arquivo? Se pudermos responder essa pergunta, tendo como informação o tamanho estimado do próprio arquivo, poderemos dimensionar o armazenamento para um repositório.
  • Este gráfico nos dá uma idéia de como é o crescimento logarítmico dos históricos de arquivos. Ele mostra 3 arquivos distintos, cada um com suas próprias características, como tamanho, freqüência de alteração e tipo. O eixo x representa o tempo, enquanto que o eixo y denota o tamanho do histórico de cada arquivo, em uma escala relativa. Notem que, apesar de cada histórico crescer em um ritmo diferente, todos eles atingem um nível de estabilidade, cada um em um patamar diferente. Se pudermos estimar esse patamar, tendo por base as características dos arquivos (tamanho estimado, tipo, etc.), conseguiremos planejar a capacidade de armazenamento para um repositório.
  • Usando algumas estatísticas sobre projetos dos quais já participamos, criamos algumas regras simples para ajudar a estimar o tamanho dos históricos. São regras que podem falhar, mas ao menos podem ajudar a fazer um chute mais consciente. Dado o tamanho de um arquivo, o tamanho do seu histórico é dado pelas fórmulas mostradas no slide. É razoável assumir que sabemos os tamanhos dos arquivos em si. Para projetos criados a partir de fontes existentes (importados para o CVS), o tamanho está disponível, basta verificá-lo. Para novos projetos, normalmente os programadores podem estimar o tamanho com base na experiência em projetos anteriores.
  • Para dimensionar a aquisição de espaço em disco para a hospedagem do CVS, o administrador deve levar em conta o bom senso. Não é preciso comprar toda a capacidade estimada desde o início do projeto. A capacidade de armazenamento pode começar menor e ser expandida ao longo do projeto ou da vida da empresa/grupo de trabalho. Uma tática comum é fixar uma ocupação máxima ideal para a área de armazenamento (80% é um valor bastante usado) e expandir a capacidade quando esse limite é atingido. Isso não é problema, pois, como veremos logo adiante, copiar, movimentar e criar back-ups de repositórios é uma tarefa bastante simples. Pelas fórmulas que vimos, fica claro que os principais vilões do repositório são os arquivos binários. Além de normalmente serem maiores que arquivos texto, seus históricos crescem a uma taxa maior. Eles também são os vilões da rede, como veremos a seguir. Porém, devemos nos lembrar das regras sobre o quê deve ficar sob o controle de versões. Muitos arquivos binários são executáveis ou bibliotecas gerados a partir da compilação de código, que não precisam ser versionados. As exceções comuns são bibliotecas de terceiros, imagens, documentos em formato Word, Excel, PDF, etc.
  • A capacidade de rede é o 2o fator mais importante a ser considerado na implantação do CVS. O seu planejamento deve levar em conta fatores diferentes daqueles que influenciam o armazenamento. Em primeiro lugar, o volume trafegado é determinado pelo tamanho do projeto em um dado instante, isto é, o tamanho das últimas revisões dos arquivos. Isso ocorre porque são os arquivos que acabam transferidos pela rede em check-outs e check-ins. O outro fator a ser levado em consideração é a taxa de acesso ao repositório (o número de check-ins e check-outs). Esse valor depende do número de programadores envolvidos, mas também de quão ativo encontra-se o projeto. Por exemplo, podemos esperar picos em vésperas de liberações. Para analisar como esse fator influenciará a rede, precisamos entender em alto nível como o CVS lida com atualizações da cópia de trabalho. Atualizações (check-outs sobre uma cópia de trabalho já existente) são muito mais freqüentes do que check-ins. A área de trabalho armazena os timestamps das últimas atualizações e o CVS compara esses com os timestamps dos arquivos locais. Se os arquivos locais forem mais recentes, provavelmente ocorreu uma modificação, mas é preciso verificar. Para isso, o CVS faz uma comparação, que ocorre no servidor . Sim, é verdade: ao invés de trazer a última revisão do repositório para comparar com a cópia local na máquina do cliente, o CVS envia a cópia local para o servidor e a compara lá com a última revisão do repositório.
  • Este slide traz mais uma regra para se fazer um chute mais orientado ao se estimar a capacidade de rede. Imaginando um programador padrão, em um projeto médio, verificamos que ao longo de um dia, ele enviará aproximadamente metade do tamanho do módulo para o servidor. Isso inclui check-ins, atualizações e comparações (o comando diff também executa a comparação no servidor). De forma análoga, o programador gerará de tráfego do servidor para sua máquina um volume de uma vez e meia o tamanho do módulo. Este tráfego é formado por check-outs (incluindo atualizações), resultados de comandos no geral (sobretudo aqueles que consultam os históricos, como diff e log ). Não é preciso dizer que essa regra é uma simplificação da realidade, pois um programador pode trabalhar em mais de um projeto no mesmo dia e, talvez mais grave, este modelo não estima picos de tráfego. Por exemplo, é comum programadores atualizarem suas cópias de trabalho pela manhã, logo após chegarem ao trabalho. Outra prática comum é submeter alterações mais ao fim do dia, para fechar suas tarefas. Entretanto, a não ser em projetos muito, muito grandes, a rede não será um problema. Use essas fórmulas apenas para ter uma base. Entretanto, a rede pode se tornar um pesadelo se alguns cuidados básicos não forem tomados. A questão é o tráfego do cliente para o servidor. Em conexões DSL, a banda de upload é geralmente bem menor que a de download. Portanto, devemos minimizar esse tráfego. Algumas dicas para isso são: manter os relógios dos clientes em sincronia com o servidor, para evitar comparações desnecessárias no servidor e usar o parâmetro –z nos clientes. Este parâmetro diz para o cliente compactar os dados antes de enviá-los para o servidor. O –z deve receber um parâmetro, de 0 a 9, indicando a compressão (0 é nenhuma compressão, 9 é compressão máxima). Um bom valor é 3 (portanto, recomende que se use –z3 ).
  • A primeira coisa a ter em mente quando pensamos na memória necessária para rodar o CVS é que ele foi escrito há mais de 15 anos. Portanto, ele sem dúvida será econômico para os padrões atuais. Uma regra bem simples é que o pico de consumo de memória será de 10x o tamanho do maior arquivo no repositório. Essa memória não tem que ser necessariamente toda em RAM: tudo bem se for preciso entrar um pouco em memória virtual. Na prática, pensando nas implantações de CVS que vi até hoje, nunca encontrei um projeto que demandasse mais do que 64MB de memória no servidor. Entretanto, é bom saber onde podem surgir problemas com a memória do servidor para que, quando isso acontecer, saibamos onde atacar. O primeiro risco são muitos programadores acessando o servidor ao mesmo tempo. Para cada requisição, o servidor faz um fork e cria um novo processo. Normalmente, esse processo usa pouca memória, mas muitos processos podem esgotar a memória do servidor. Em um caso extremo, eles poderiam até esgotar o número de file descriptors do servidor, mas isso é fácil de se contornar. Outro risco são módulos muito grandes, sobretudo aqueles com muitos arquivos em um mesmo diretório. Se a rede for lenta, a memória consumida pelo processo principal do CVS pode crescer até o tamanho total dos arquivos em um único diretório. Isso não é um problema se os arquivos do projeto estão bem distribuídos entre diretórios, como acontece em sistemas escritos na linguagem Java. Por fim, outro problema pode acontecer com arquivos muito grandes. Comandos como diff , commit e update fazem comparações de diferenças no servidor. Para isso, o CVS carrega pelo menos duas cópias do arquivo em memória (a cópia antiga e a nova). Portanto, arquivos muito grandes podem esgotar a memória do servidor.
  • A capacidade de processamento é a menor das preocupações ao se dimensionar um servidor para o CVS. Mais uma vez, lembrem-se de que ele é um sistema com mais de 15 anos: quando ele foi criado, processadores de 33MHz eram top. A regra aqui é que qualquer máquina que sirva como servidor comportará o CVS, bastando não enchê-la com muitos outros serviços, sobretudo aqueles que demandem I/O. Por exemplo, não é uma boa idéia combinar um servidor CVS com um servidor de arquivos. Obviamente, o problema não é o processador, mas a arquitetura da máquina como um todo. Portanto, procurem máquinas com um barramento rápido e uma boa capacidade de I/O para evitar problemas.
  • Passamos agora à instalação propriamente do sistema CVS. Não estamos falando ainda de configurar usuários e senhas, nem de criar o repositório, apenas de disponibilizar os binários no servidor e nos clientes. O primeiro passo é definir que sistema operacional será utilizado no servidor e nos clientes. É possível usar sistemas operacionais diferentes, desde que se tome algum cuidado com os editores, na configuração dos fins de linha. Abordaremos aqui as duas principais escolhas, UNIX (usaremos o Linux) e Windows. Também mencionaremos o caminho a se seguir para a instalação do CVS em Macintosh, mas não teremos laboratório para o Mac. O próximo passo é escolher entre as duas distribuições existentes de CVS: o GNU CVS, que é o CVS “original”, e o CVSNT, um derivado do CVS que hoje é mantido por uma empresa e tem uma versão comercial, na linha da RedHat e outras empresas que têm montado negócios sobre sistemas open-source. Se optarmos por uma distribuição em código-fonte (tanto o GNU CVS quanto o CVSNT deixam essa opção), o próximo passo é compilar a distribuição. Entretanto, a não ser em casos de necessidades muito específicas, o recomendado é usar uma distribuição binária. Em seguida, devemos instalar a distribuição, seja manualmente (em geral necessário apenas nos casos de distribuições em fonte) ou com um instalador (o caso quando se usa uma distribuição binária). Por fim, testamos a instalação, verificando se os executáveis estão disponíveis. Com isso funcional, podemos seguir adiante e configurar usuários, criar repositórios e módulos.
  • O CVS não impõe nenhuma limitação ao sistema operacional a ser utilizado, tanto no cliente quanto no servidor. As distribuições disponíveis hoje podem ser executadas em qualquer variante de sistema UNIX e nas versões mais recentes de sistemas Windows e Macintosh. A questão mais relevante na instalação do CVS é escolher um servidor (hardware e sistema operacional) que atenda as demandas de acesso, tanto de acesso a disco quanto a rede. Há algumas restrições, porém. Se o Windows for escolhido como servidor, a distribuição recomendada é o CVSNT. A versão do Windows também deve ser NT, 2000 ou XP – versões como 98 e anteriores não podem ser utilizadas como servidor. Executar o servidor em um Macintosh não é muito utilizado, portanto, isso pode ser considerado uma restrição. Com o MacOS X talvez isso possa deixar de ser um problema. Deve-se tomar cuidado na escolha de versões compatíveis de SSH para clientes e servidor, caso esse protocolo seja utilizado. Com o uso de plataformas diferentes deve-se também dar atenção às quebras de linha – o CVS as trata corretamente, mas os editores podem se confundir.
  • Existem duas distribuições do CVS, ambas derivadas dos mesmos fontes criados por Brian Berliner. O GNU CVS é a distribuição considerada original, mantida pela Free Software Foundation, uma entidade sem fins lucrativos. Ele é licenciado pela GNU Public License, uma licença de código aberto. É, portanto, software livre, que pode ser utilizado sem custo algum. O CVSNT é uma derivação dos fontes do GNU CVS, feita por volta de 1999, inicialmente com o propósito de portá-lo para o Windows NT. Com o tempo, a distribuição CVSNT evoluiu e passou a implementar novas funcionalidades, diferenciando-o um pouco do GNU CVS. Mais recentemente, uma empresa, chamada March-Hare, passou a oferecer serviços profissionais e treinamento sobre o CVSNT, além de continuar sua evolução. Defeitos também têm sido corrigidos mais rapidamente no CVSNT. O pacote básico do CVSNT continua licenciado pela GPL e oferecido sem custo. Tanto o GNU CVS quanto o CVSNT podem ser instalados em Windows e em UNIX (usaremos aqui o Linux como referência de sistema UNIX). Entretanto, o código do GNU CVS foi criado para sistemas UNIX e pode apresentar alguns comportamentos indesejados em Windows. Inclusive, ele não pode ser compilado diretamente no Windows, sendo necessário o uso das ferramentas Cygwin. Existe, porém, uma configuração recomendada. Para sistemas UNIX, o GNU CVS é o preferido, por ser a mais utilizada e já vir instalada na grande maioria dos sistemas. No Linux, por exemplo, o CVS já vem no pacote básico da maioria das distribuições (RedHat, Slackware, Debian, SuSE). Já para Windows e Mac, o CVSNT é mais recomendado, pois foi especialmente adaptado para esses sistemas. Entretanto, pelo fato do MacOS X ser derivado do FreeBSD, o GNU CVS pode ser uma melhor opção para essa versão de Macintosh. Por fim, existe ainda a recomendação de que o servidor CVS seja instalado em uma máquina UNIX, com o GNU CVS. A razão disso é a maior maturidade dessa configuração.
  • Caso se escolha o GNU CVS, existem duas vertentes: versões estáveis e versões evolutivas. As versões estáveis são bastante maduras, estão em uso por um longo tempo e trazem sobretudo correções de defeitos e melhorias de segurança. A linha estável atual é a 1.11, sendo 1.11.21 a última versão disponível ao final de novembro de 2005. Já as versões evolutivas introduzem novos recursos (por exemplo, novos comandos) e melhorias arquiteturais significativas. A linha evolutiva atual é a 1.12, sendo 1.12.13 a última versão em novembro de 2005. Por qual das linhas optar? Quem conhece os softwares da GNU sabe que eles são muito sérios quanto à qualidade dos produtos e são conservadores quanto à liberação de novas versões. Portanto, as versões evolutivas podem ser consideradas de qualidade de produção. Veremos neste treinamento alguns novos recursos que justificam seu uso. Por outro lado, se você julgar que não usará esses recursos e tiver uma política bastante conservadora quanto a seleção de software, pode optar pelas versões estáveis. Neste treinamento, usaremos a versão evolutiva do GNU CVS. Outra observação. Dentro de uma linha (a mesma idéia de linha de código), as versões são chamadas minor releases , pois acrescentam pequenas correções de defeitos e, eventualmente, melhorias de segurança. Não se preocupe em ter sempre a última versão instalada. As melhorias/correções são em geral muito pontuais e específicas. Por exemplo, para este treinamento, utilizei no Linux a versão 1.12.9 do CVS, disponível na última distribuição do Debian. Já o CVSNT nos deixa menos opções. No site do produto, vemos que a versão paga, chamada CVS Suite, encontra-se na versão 2.5.02. Já a versão open-source está na versão 2.5.03, praticamente o mesmo código. Uma observação importante: o CVSNT é uma derivação do GNU CVS a separação foi feita quando o GNU CVS estava na versão 1.11. Portanto, os recursos entre CVSNT e o GNU CVS 1.12 podem variar mais.
  • A instalação do CVS é bastante simples. Em primeiro lugar, raramente será necessário obter uma distribuição fonte e compilá-la. Isso só se justifica se for preciso alterar o código do CVS (por exemplo, para implementar uma nova forma de autenticação), ou se sua empresa tiver alguma norma que obriga a se ter o código-fonte dos sistemas utilizados na empresa. Nas instalações de binários, sempre há um programa instalador, qualquer que seja a plataforma e a distribuição escolhida. Nosso próximo lab exercitará a instalação em Linux e Windows. Uma vez terminada a instalação, basta tentar executar o comando cvs para verificá-la. O comando cvs –v mostra a versão instalada na máquina onde ele é executado, seja um cliente ou o servidor. Já o comando cvs version mostra a versão do cliente (instalação local) e, se o comando for configurado para acessar um servidor remoto, ele mostra a versão instalada no servidor também. No próximo lab testaremos a nossa instalação e, para isso, veremos como configurar o cliente CVS para acessar um servidor remoto.
  • Neste lab, instalamos o CVS e, em seguida, testamos a instalação. Consulte o material dos laboratórios.
  • O passo seguinte à instalação do CVS (servidor e cliente) é a criação do repositório. Sem um repositório, não há onde armazenar os históricos e, portanto, o CVS não tem utilidade! O ideal é que cada programador trabalhe em apenas um repositório. Isso permite alguns “confortos” a ele, como, por exemplo, configurar uma variável de ambiente apontando para o repositório, o que dispensa a necessidade do uso do parâmetro –d para boa parte dos comandos CVS. Portanto, uma boa prática é criar um repositório por empresa ou, em grandes empresas, um repositório por departamento. Assim, raramente um programador terá que se envolver em projetos localizados em repositórios diferentes. Uma exceção a essa regra é o programador envolvido em projetos open-source, naturalmente distribuídos. Um repositório pode ser criado em qualquer área de um disco local da máquina escolhida como servidor CVS. Entretanto, algumas dicas são: escolher uma área com back-ups freqüentes (de preferência diários) e usar um sistema de arquivos que não trave o servidor se atingir o limite. Portanto, para sistemas UNIX, sugere-se um filesystem diferente do / , tal como os montados normalmente em /var ou /export . Uma opção comum é /var/lib/cvs , que já em configurada em muitas distribuições Linux. Já para o Windows, pode ser escolhido o diretório D:\\cvs , assumindo-se que o sistema operacional está instalado no drive C: . Outro aspecto importante é escolher um usuário no servidor para ser o “dono” de todo o repositório. Isso significa que todos os subdiretórios do repositório e os arquivos de histórico serão desse usuário. A raiz do repositório deve ser desse usuário também. Uma escolha comum é um usuário chamado cvs , de um grupo cvs . Em termos gerais, uma boa política é tratar o servidor CVS como um servidor de arquivos. Portanto, back-ups, disponibilidade, regras de acesso e outros parâmetros já usados na infra-estrutura de sua empresa podem ser aplicados ao servidor CVS.
  • Um repositório CVS é criado usando-se um comando do próprio CVS. Este comando é init . Ele cria um diretório em um local especificado, contendo os arquivos de configuração de um repositório. Estes arquivos são os já mencionados “arquivos administrativos”, que veremos em detalhe logo adiante. Uma estrutura de diretórios contendo arquivos administrativos já pode ser considerada um repositório, mesmo não tendo ainda nenhum histórico. Logo após criado, um repositório traz a configuração inicial (padrão) dos arquivos administrativos e nenhum módulo; pode ser considerado, portanto, um repositório vazio. O comando init não recebe nenhum parâmetro. Como então é especificado o local de criação do repositório? Da mesma forma que para o comando checkout , como vimos no módulo anterior. Há duas opções: usar a opção –d (chamada “global” pois pode ser utilizada com qualquer comando) ou definir a variável de ambiente $CVSROOT . Basta pensarmos por um momento para percebermos que, com init , é muito mais prático usarmos a opção –d . O init é feito apenas uma vez por repositório, portanto, não haverá nenhum ganho em definir a variável $CVSROOT . Inclusive, nem se recomenda ao administrador de sistemas definir a variável $CVSROOT em seu ambiente, para que ele seja forçado a sempre especificar o repositório na linha de comando. Além do mais, ele não deve ter nada contra linhas de comando grandes... Entretanto, se o administrador se distrair e chamar o comando init especificando um repositório existente, não há perigo algum. O comando init não sobrescreve nenhum arquivo em um repositório que já exista.
  • O comando init é um dos mais simples do CVS. Ele não recebe parâmetros nem opções específicas. A única informação usada por init é a localização do repositório a ser criado que, como vimos, pode ser especificada pela opção global –d ou pela variável de ambiente $CVSROOT . Com init , assim como os outros comandos, a opção –d tem preferência, isto é, ela é usada primeiro, se presente.
  • Neste laboratório, cada aluno irá criar um repositório em sua máquina usando o comando init , entrar no diretório criado e examinar os arquivos existentes lá. Em seguida, faremos um check-out do diretório CVSROOT e, na cópia de trabalho, alteraremos o arquivo modules , que define módulos no repositório, incluindo apenas um comentário. Faremos então um check-in da alteração e veremos como o histórico do arquivo se comporta.
  • Vamos conhecer a estrutura do repositório, por uma questão de informação e curiosidade. Não é recomendado ler ou escrever os arquivos do repositório diretamente, a não ser que você saiba muito bem o que está fazendo. O formato do repositório pode mudar de versão para versão do CVS, portanto, o mais seguro é sempre acessar o repositório através dos comandos CVS. Assim, se o repositório mudar de formato, os comandos serão atualizados de forma compatível. Olhando para o primeiro nível do repositório, vemos que ele é um diretório comum, contendo o diretório administrativo CVSROOT . Como vimos no lab, os arquivos administrativos (configuração e controle) ficam sob CVSROOT . Ele inclui tanto os históricos desses arquivos quanto suas cópias mais recentes. As cópias são usadas para configurar o comportamento do CVS e nunca devem ser editadas diretamente. Deve-se sempre fazer um check-out de CVSROOT para uma área de trabalho, editar aí as cópias e realizar um check-in para atualizar o repositório. Lado a lado com CVSROOT vemos outros diretórios, cada um correspondente a um módulo (veremos como criar e importar módulos adiante). A estrutura desses diretórios é muito similar à dos projetos correspondentes, com a diferença que, em vez dos arquivos, eles contêm históricos. Um histórico tem o mesmo nome do arquivo correspondente, seguido de ,v . Nos laboratórios, vimos brevemente o formato de um arquivo de histórico, também chamado arquivo RCS. Um módulo pode ainda conter outros arquivos de controle, muito específicos e que provavelmente nunca teremos que examinar ou conhecer. Eles são citados aqui apenas para sua informação. Em cada subdiretório de um módulo pode existir um diretório de controle chamado CVS , que armazena um arquivo chamado fileattr . Esse arquivo armazena atributos dos arquivos no subdiretório onde ele se encontra, para a configuração do comando watch . Veremos o comando watch na parte avançada deste treinamento. Outro diretório que pode surgir é chamado Attic . Ele armazena históricos de arquivos que não estão no tronco principal do módulo (arquivos que foram criados dentro de um ramo). Podem surgir no repositório arquivos que o CVS usa para controlar o acesso simultâneo. São arquivos temporários, usados para “travar” diretórios do repositório para leitura ou escrita. Esses arquivos têm os formatos #cvs.lock , #cvs.rfl , #cvs.wfl . O CVS também pode armazenar arquivos no diretório temporário do sistema ( /tmp ou C:\\TEMP ), para controlar eventuais quedas do servidor.
  • Como vimos no início do treinamento, módulo e projeto são dois termos idênticos para o CVS. Por definição, são unidades independentes de trabalho, tais como sistemas, componentes, arquivos de projeto, artigos técnicos, sites da Web, etc. O CVS não tem conhecimento do propósito de um módulo – para ele, um módulo é simplesmente um diretório sob a raiz do repositório. Portanto, cabe a quem usa o CVS (em geral, ao gestor de configuração ou ao gerente do projeto) definir módulos apropriados. A única forma de se criar um projeto do CVS é importando diretórios e arquivos existentes para o CVS. É até possível criar um projeto sem arquivo algum, importando um diretório vazio e depois usando o comando add para adicionar arquivos ao repositório. Mas normalmente começamos um projeto criando e editando alguns arquivos em nosso próprio computador, somente depois nos preocupamos em colocá-los sob o controle de versões. Portanto, essa restrição não é um problema. Apesar deste módulo ter foco no administrador de sistemas, a tarefa de importação de módulos geralmente cabe ao gestor de configuração, ou ao desenvolvedor sênior. Isso porque não é preciso nenhum acesso especial à máquina do repositório para tal; a importação é feita usando-se um comando do CVS. A importação pode ser dividida em 3 partes: Na preparação, reunimos o conjunto inicial de arquivos a serem colocados sob o controle de versões. É importante tentarmos definir uma estrutura praticamente definitiva para esses arquivos, pois o CVS tem limitações quanto à re-nomeação e a remoção de diretórios. Veremos essas limitações mais adiante, bem como contorná-las. A importação propriamente dita é a execução do comando import , que veremos no próximo slide. Um passo opcional é a declaração no comando modules. Podemos incluir uma linha nesse arquivo declarando o módulo. Isso permite que o módulo seja listado pelo comando checkout , quando se especifica a opção –c ou –s . Logo adiante veremos a sintaxe de modules e como incluir essa linha.
  • O comando import é usado não somente para criar um novo projeto, mas também para atualizar projetos existentes com um conjunto de arquivos fornecidos por terceiros. Lembre-se de que uma das motivações para a criação do CVS é a capacidade de controlar, em diferentes ramos, código da equipe interna e código fornecido por terceiros para um mesmo sistema ou projeto. Portanto, import oferece essa possibilidade. Veremos como criar e utilizar explicitamente ramos mais adiante no treinamento, mas nosso conhecimento conceitual nos permitirá entender como import funciona. O comando import processa todos os arquivos presentes no diretório de onde ele foi executado e os importa para o módulo especificado. Portanto, observe que import deve ser executado de dentro de um diretório contendo exclusivamente os arquivos a serem importados. O comando import recebe opções globais e específicas, assim como os demais comandos. Consulte um guia para detalhes sobre todas as opções de import . As opções específicas mais importantes são: – m , que permite especificar uma mensagem para a importação (assim como vimos com commit , no passeio pelo CVS); – I , que lista um conjunto de padrões de nomes de arquivos a serem ignorados pela importação. O CVS já tem um conjunto de arquivos ignorados por default. Veremos mais sobre arquivos ignorados no módulo de uso básico do CVS. – W , que lista um conjunto de padrões de nomes de arquivos a serem filtrados pela importação. Isso permite, por exemplo, que alguns arquivos sejam incluídos no repositório como binários, com base na sua extensão. Falaremos mais sobre filtros ( wrappers ) no módulo de uso básico do CVS. O nome do projeto a ser criado ou atualizado é dado pelo argumento nome_projeto . Os outros argumentos são usados para controlar ramos e liberações. O segundo argumento, ramo_fornec , é o nome de um ramo que irá armazenar as revisões criadas pela importação. Caso não exista, esse ramo será criado. Os demais argumentos, etiq_versão , são etiquetas (ao menos uma) que serão aplicadas sobre as revisões criadas pela importação, marcando a liberação importada.
  • Neste lab treinaremos a importação de projetos para o CVS. Veremos não só a criação de um novo módulo, mas também a importação de arquivos para módulos existentes e forçaremos um cenários de conflito. Entenderemos também o funcionamento das opções que controlam arquivos ignorados e filtrados.
  • Outra situação em que podemos querer importar um projeto para o CVS é quando ele já está em outro sistema de controle de versões. Nesse caso, o ideal é importar mantendo os históricos dos arquivos. Existe basicamente uma forma de se importar históricos para o CVS: convertendo-os para o formato RCS. Portanto, para quem está migrando do RCS ou de outro sistema de utiliza esse formato (por exemplo, o Perforce), basta criar um diretório para o projeto logo abaixo da raiz do repositório e copiar os arquivos para lá, mantendo a estrutura dos subdiretórios. Para outros SCVs, existem scripts que convertem seus formatos específicos para o RCS. Por exemplo, a distribuição GNU CVS disponibiliza conversores para o SCCS e o PVCS. É improvável que sistemas comerciais disponibilizem esse tipo de conversor, mas isso acontecer para outros sistemas open-source, ou pode ser fornecido por grupos de usuários do CVS. No pior caso, uma boa alternativa é exportar as liberações mais relevantes, importá-las sucessivamente no CVS e, por fim, exportar e importar as últimas revisões do projeto.
  • Para falarmos em back-ups, é preciso ter em mente que um repositório CVS nada mais é do que uma árvore de diretórios no sistema de arquivos do servidor. Portanto, as cópias podem ser feitas usando as ferramentas já empregadas no dia-a-dia da administração de sistemas para back-ups de áreas pessoais, diretórios de sistemas, etc. Uma observação importante: as ferramentas de back-up devem ser capazes de restaurar a cópia exatamente como ela era originalmente: estrutura, propriedades, permissões e atributos como data de atualização devem ser mantidos como no original. Gerenciar back-ups do CVS envolve as seguintes atividades: congelar o repositório, para garantir que a cópia não seja feita em estado inconsistente; copiar os dados em si, uma atividade simples, mas que pode tomar tempo; restaurar o back-up e espelhar um repositório, que significa criar cópias em outros servidores para apenas leitura. Veremos essas atividades em maior detalhe a seguir.
  • Congelar um repositório significa impedir que usuários modifiquem seu estado, tipicamente, os históricos dos arquivos. Essa atividade é um pré-requisito para a cópia, pois garante que ela seja feita sobre um conjunto inconsistente de dados. Um exemplo dessa situação é um programador, ao fim de um dia de trabalho, realizando o check-in de vários arquivos alterados. Se a cópia ocorrer no meio desse processo, a “foto” pode ser inconsistente, incluindo até arquivos que não compilam entre si. Para atingir esse objetivo há várias alternativas, algumas bastante radicais. Com repositórios remotos, há opções como desligar o processo servidor, impedir logins na máquina do servidor (por exemplo, deixando-a em modo single user ) ou ainda ligar um firewall à frente do servidor, ou simplesmente puxar seu cabo de rede. A forma mais limpa e flexível é travar o repositório em modo exclusivo para leitura. Ela usa um recurso do próprio servidor CVS para impedir que sejam feitas alterações em históricos e, ao mesmo tempo, permite que usuários continuem usando o repositório para leitura, o que atende à maioria dos casos. Imagine, por exemplo, um servidor CVS de um grande projeto open-source. Não há horários de baixo acesso, o serviço deve estar disponível 24x7. Os materiais do aluno incluem dois scripts, freeze.sh e unfreeze.sh, retirados do livro “Essential CVS”, para congelar e descongelar um repositório CVS.
  • A cópia do repositório deve iniciar após o seu congelamento. Use uma ferramenta de back-up que preserve os atributos dos arquivos, sobretudo propriedades e permissões, que são as configurações de segurança do repositório, como veremos a seguir. Um excelente exemplo de ferramenta que é simples, acessível em qualquer sistema UNIX e respeita tais atributos é tar , o Tape Archiver . Para restaurar um back-up, é preciso disparar a extração dos arquivos da cópia, garantindo que os atributos estão sendo preservados. Durante esse processo, é preciso congelar o repositório não só para escrita, mas também para leitura, pois usuários não podem tentar acessá-lo enquanto ele estiver em um estado inconsistente. Isso pode ser feito alterando o script freeze.sh para criar uma trava de escrita. Em relação à ordem de restauração, é importante que o diretório CVSROOT seja restaurado antes; os projetos podem ser restaurados em qualquer ordem. Terminada a restauração, peça ao usuários para realizarem um novo check-out de seus projetos, criando novas áreas de trabalho. Peça que eles verifiquem alterações pendentes nas cópias antigas e as copiem para as novas áreas de trabalho.
  • Espelhar um repositório pode ser uma atividade necessária em grande empresas, que precisam compartilhar projetos entre diferentes unidades e departamentos, mas sobretudo em instituições dedicadas a open-source. Nessas instituições, tais como FSF, Apache e SourceForge, existem repositórios exclusivos para os “ commiters ” que, como o nome diz, são programadores que fazem commits, isto é, submetem alterações no código-fonte. O grande público acessa os fontes por repositórios para somente leitura, com menor disponibilidade e menor desempenho. O requisito de que os espelhos sejam para somente leitura é necessário: o CVS não consegue conciliar modificações em repositórios distintos. Existe uma ferramenta em desenvolvimento para implementar isso, ainda não muito usada, o CVSup. Os repositórios-espelho podem estar na mesma máquina do original, o que pode não ser interessante por questões de memória ou desempenho, mas pode ser a única opção em empresas menores. No caso mais geral, os espelhos estarão em redes distantes. O espelhamento é muito parecido com o back-up: congele o repositório origem (permita somente leitura) e o repositório destino (como este vai ser alterado, bloqueie-o totalmente). Faça então a cópia usando uma ferramenta para back-ups remotos, como rsync (a opção –e usa ssh , para transmissão segura). Terminada a cópia, descongele ambos os repositórios.
  • Em algumas situações pode ser interessante ou necessário editar diretamente o repositório, movendo ou removendo arquivos e diretórios. No mundo ideal, todas as operações sobre o repositório seriam feitas pelos comandos CVS (por exemplo, admin , remove e add ), mas isso nem sempre nos atende. É possível fazer essas operações sobre a raiz do repositório, sobre um módulo ou sobre arquivos e diretórios dentro de um módulo. Pode haver várias motivações que justifiquem essas operações. Para um repositório, o mais comum é desejar movê-lo para um novo disco (porque ele cresceu demais) ou para uma área com procedimentos de back-up. Com um módulo, pensamos em movê-lo quando bolamos um nome melhor para ele, ou quando o projeto muda de foco e é preciso mudar seu nome. Já arquivos e diretórios dentro de módulos têm que ser movidos (renomeados) quando o projeto em si demanda isso: por exemplo, um refactoring do código pode renomear diversos arquivos e diretórios. Já a remoção, obviamente ela acontece quando um item não é mais utilizado, seja um repositório, um módulo ou um mero arquivo.
  • Encare a movimentação de um repositório como a criação e posterior restauração de um back-up. Os passos, portanto, são similares, como mostrado neste slide. Muita atenção para fazer a cópia de forma a manter os atributos sobre as quais já falamos: propriedade (dono/grupo), permissões e data de atualização. Uma opção simples e eficaz é usar a opção –a para o comando cp , em sistemas UNIX. Terminada a cópia, peça para os usuários atualizarem suas variáveis $CVSROOT e outros arquivos de configuração que façam referência à raiz do repositório e realizarem o check-out criando novas áreas de trabalho. Eles devem então submeter quaisquer alterações pendentes para o novo repositório. Ao remover um repositório, garanta que isso é realmente o que você deve fazer. Por via das dúvidas, faça um back-up e verifique se há scripts ou executáveis que eram utilizados pelos arquivos administrativos do repositório – eles podem agora ser removidos também. Por fim, remova recursivamente a raiz do repositório, usando, por exemplo, rm –rf .
  • Mover é o mesmo que renomear um módulo, pois o que os usuários verão é que o projeto mudou de nome. Há duas opções distintas: 1) mover o diretório no repositório, o que torna o nome original inacessível, invalidando as áreas de trabalho dos usuários do módulo; 2) criar uma nova entrada no arquivo administrativo modules , o que mantém o nome original disponível e não requer acesso direto (shell) ao servidor CVS. A opção 2) é a preferida na maioria dos casos. Para remover um módulo, faça antes um back-up dos dados e verifique se há referências ao diretório a ser removido no arquivo modules . Elimine-as, se houver alguma. Por fim, remova o diretório do módulo, recursivamente.
  • Mover um arquivo (tanto renomeá-lo quanto trocá-lo de diretório) é uma tarefa que pode nos parecer corriqueira num projeto, mas o CVS não possui um comando para isso. Há 3 alternativas, em ordem crescente de complexidade. Renomear o arquivo na área de trabalho, então removê-lo do repositório com cvs remove , depois adicionar o “novo” arquivo com cvs add . É uma opção simples, que qualquer usuário pode executar e preserva as liberações antigas, pois elas continuam referenciando o arquivo removido, enquanto novas revisões referenciam o novo arquivo. Porém, o histórico do arquivo é interrompido: o novo arquivo começa seu histórico na revisão 1.1 e não há nenhuma ligação dele com o arquivo removido. Renomear o arquivo no repositório. O processo é mais complicado e envolve acesso privilegiado ao repositório (é preciso entrar em um shell com o usuário root ou cvs ). Os usuários precisam liberar suas áreas de trabalho e o repositório tem que ser congelado antes do procedimento. Como vantagem, o histórico é preservado, mas liberações anteriores podem ser danificadas, pois farão referência ao novo nome (scripts de compilação podem falhar). Copiar o arquivo antigo para o novo nome e então mover o antigo para o diretório Attic, criando uma revisão “morta”. Este procedimento é ainda mais complicado que o anterior. Também exige o congelamento do repositório e envolve um número maior de passos. Ele preserva o histórico do arquivo movido e liberações antigas, que passam a apontar para nome antigo, agora uma revisão morta. Algumas situações inesperadas podem ocorrer se ramos estiverem sendo usados. No geral, a sugestão é usar a alternativa mais simples: remove e add . Poucas vezes é útil ter o histórico 100% fiel à realidade do projeto. Em outras palavras, o projeto dificilmente será prejudicado se o CVS não tiver a informação de que o arquivo B antes se chamava A . O mais importante é preservar liberações antigas, o que ocorre com este método.
  • Eis um comportamento do CVS que causa alguns incômodos: não há comandos para a manipulação direta de diretórios. Em outras palavras, diretórios não são tratados como arquivos, assim como ocorre em outros SCVs, como o ClearCase, onde diretórios têm inclusive revisões, assim como arquivos. Um diretório é adicionado pelo comando add , assim como arquivos, mas não é possível invocar o comando remove sobre diretórios. Para se remover um diretório, é preciso remover todos os arquivos debaixo dele. Entretanto, ele continuará sendo visto nas áreas de trabalho, a não ser que a opção –P (purga) for especificada para checkout e update . Para mover/renomear um diretório, a situação é similar à que vimos com arquivos. A primeira opção é fazer todo o procedimento a partir de uma cópia de trabalho, criando o novo diretório localmente, depois movendo todos os arquivos na cópia, removendo-os do antigo local no repositório e por fim adicionando os novos arquivos. Essa opção é pior que a correspondente para a renomeação de arquivos, pois os históricos de todos os arquivos sob o diretório são interrompidos. Se esse diretório é próximo da raiz do módulo, isso significa perder os históricos de grande parte dos arquivos do projeto. Uma opção melhor é simplesmente mover o arquivo no repositório. Isso afeta liberações anteriores, pois scripts de compilação que faziam referência ao nome antigo vão parar de funcionar. Uma terceira opção, a melhor neste caso, é copiar o diretório para o novo nome diretamente no repositório e depois, a partir de uma área de trabalho, remover todos os arquivos sob o diretório antigo com cvs remove . As liberações anteriores serão preservadas, assim como os históricos. Entretanto, continuará sendo preciso usar a opção –P para checkout e update para que o diretório vazio não seja visto.
  • O CVS, como qualquer sistema computacional, envolve questões relativas a segurança da informação. Para um trabalho completo, é preciso pensar na segurança da arquitetura como um todo. Isso envolve os itens listados neste slide. Alguns deles, como a segurança do servidor CVS e das estações de trabalho clientes, onde são criadas as áreas de trabalho, são questões corriqueiras em qualquer ambiente distribuído. Não é escopo deste treinamento detalhar tais técnicas. O mesmo se aplica à segurança dos back-ups do repositório. Daremos destaque a dois aspectos mais específicos ao CVS: as permissões na área de armazenamento do repositório, que controlará quais usuários terão que tipo de acesso sobre os históricos, e os métodos de acesso ao repositório, que definirá o transporte das informações entre clientes e servidor.
  • Como o repositório CVS pode ser considerada uma árvore de diretórios comum, a segurança dos históricos é implementada pela segurança do sistema de arquivos (filesystem) do servidor. Portanto, cada sistema operacional terá sua abordagem especifica, mas os conceitos são fundamentalmente os mesmos. Neste treinamento, como estamos dando ênfase em servidores UNIX, discutiremos as configurações neste tipo de sistema. Começando pela raiz do repositório, já vimos alguns aspectos no lab de criação do repositório. Naquela oportunidade, criamos um repositório, dando-lhe um dono (o usuário cvs ) e deixando-o com permissão de leitura, escrita e execução para este dono e seu grupo (o grupo cvs ) e permissão de leitura e execução para os demais usuários. Também ligamos seu bit SGID, para que subdiretórios propaguem essas permissões. Em relação a essa configuração, não há nenhuma informação nova neste slide, apenas que o grupo cvs deve ser associado somente aos usuários que devem ter a capacidade de criar novos módulos (projetos). Tipicamente, estes usuários incluem o administrador do CVS, o gestor de configuração e gerentes de projetos. O diretório CVSROOT é também merecedor de atenção especial com relação a permissões. Para que o CVS funcione corretamente, todos os usuários devem ter acesso de leitura a todos os arquivos sob CVSROOT , os arquivos administrativos. Há dois arquivos que devem ter permissão de escrita para todos os usuários: history , que armazena o histórico de operações sobre o repositório, e val-tags , que guarda informações sobre as etiquetas. Os demais arquivos devem ter permissão de escrita somente para usuários avançados, tais como o administrador do CVS e o gestor de configuração.
  • O CVS permite que permissões no repositório sejam controladas no nível de diretórios apenas. Portanto, se dois arquivos puderem ser alterados por perfis diferentes de usuários, devem estar em diretórios diferentes. Essa limitação existe devido à forma como o check-in funciona. O CVS cria uma cópia temporária do histórico, para evitar que quedas deixem o arquivo inconsistente, e só depois joga essa cópia por cima do histórico original. Como conseqüência, as permissões e propriedade são sempre sobrescritas pela forma como o CVS cria o temporário. Por isso, o dono do arquivo de histórico é sempre quem fez o último check-in. A segurança em projetos CVS é basicamente garantida por grupos de usuários. Cada projeto (e, caso se queira controles mais finos, cada subdiretório do projeto) deve ter um grupo associado a ele, com as permissões apropriadas: o dono com leitura, escrita e execução, o grupo com leitura, escrita e execução e outros com apenas leitura e execução. Como vimos em um lab anterior, o bit SGID deve ser ativado na raiz do módulo, o que faz com que as permissões sobre subdiretórios sejam propagadas. Para remover o acesso de leitura a um diretório, remova as permissões de leitura e execução dele para outros.
  • Para permitir que módulos de um repositório tenham permissão de somente leitura, é preciso alterar uma configuração geral do repositório: o local de criação das travas. Por default, o CVS cria travas dentro do próprio diretório do projeto. Como vimos anteriormente, o CVS usa travas de leitura e de escrita em seus comandos. Portanto, se tiramos a permissão de escrita do módulo para outros (falando em sistemas UNIX, temos permissões para o dono, para o grupo e para outros), eles não conseguirão sequer ler o módulo. Por outro lado, se dermos essa permissão, eles conseguirão alterar os arquivos do módulo. A saída para isso é alterar a propriedade LockDir do arquivo administrativo config, que controla configurações variadas do repositório. A solução é fazer com que essa propriedade aponte para um diretório fora do repositório. O CVS criará nesse diretório uma estrutura semelhante à do repositório, porém cada diretório armazenará somente as travas do diretório correspondente do repositório. Veremos esse comportamento no lab. Se essa configuração for feita e se desejar impedir que usuários fora do grupo de um projeto possam ler os arquivos, deve-se tirar as permissões de leitura e execução de outros. Assim, mesmo que seja possível criar as travas de leitura, os históricos em si não poderão ser lidos.
  • Neste lab aprenderemos como controlar permissões em projetos no CVS. Criaremos projetos e grupos correspondentes, em seguida associaremos alguns usuários a estes grupos e verificaremos o funcionamento das permissões.
  • Como vimos no módulo de introdução, a arquitetura do CVS permite que ele trabalhe tanto com repositórios locais, funcionando como um programa independente, como com repositórios remotos, no estilo cliente/servidor. Como optar por cada alternativa? Em projetos pessoais ou com equipes que usam um mesmo servidor por terminais “burros” (ou estações sem disco local), a melhor opção é o repositório local. Já em projetos distribuídos entre diversas empresas ou até países, bem como em equipes onde cada um tem sua própria estação de trabalho com disco local, a melhor escolha é o uso remoto. Esta opção também permite configurações mais finas de segurança, apesar de levantar questões e potenciais fragilidades inexistentes no uso local. Veremos adiante mais detalhes sobre repositórios remotos.
  • O CVS disponibiliza vários métodos para acesso remoto a repositórios. Vimos no módulo de introdução que um repositório pode ser especificado através da opção global –d ou da variável de ambiente $CVSROOT , no formato exibido neste slide. Naquela oportunidade, não falamos do elemento método , que é aqui descrito. As opções são aquelas exibidas no slide. Dois dos métodos mais utilizados são ext , que permite privacidade com o uso de ssh sobre conexões inseguras, e pserver , que é de simples funcionamento e adequado para redes seguras. De acordo com o método especificado, alguns dos elementos podem ser omitidos. Por exemplo, não é necessário informar um usuário com os métodos local e fork . A rigor, o único componente obrigatório do formato é raiz , pois até método pode ser omitido (o default é local )
  • Os métodos local e fork são usados para acessar repositórios locais, isto é, localizados em um sistema de arquivos acessível pela máquina onde o cliente é executado (o sistema pode ser, por exemplo, uma área compartilhada por várias máquinas). Com estes métodos, a segurança sobre o repositório é dada pela segurança do sistema de arquivos sobre o qual ele está implementado. Usar o método local é rigorosamente igual a especificar diretamente o caminho do repositório, como em –d /var/lib/cvs . Observe que, neste modo, o CVS roda apenas em modo cliente, não havendo nenhum tipo de comunicação cliente/servidor. O método fork força o CVS a funcionar no modo cliente/servidor, mesmo acessando um repositório na própria máquina onde o cliente foi executado. O servidor é criado através de um fork do processo cliente, daí o nome do método. Portanto, cliente e servidor executam sob o mesmo usuário: aquele que invocou o cliente. Este método tem como principal objetivo a depuração da comunicação cliente/servidor, pois isola possíveis problemas da rede.
  • Os métodos ext e server são muito similares: ambos utilizam um shell remoto para conectar o cliente ao servidor. A diferença é que server usa um shell embutido no CVS (é uma versão do rsh ) e depende de um processo servidor em execução na máquina do repositório (o comando server ), enquanto que ext permite que um shell ext erno seja utilizado, tal como o rsh ou o ssh . O SSH é o protocolo mais utilizado com o método ext , pois criptografa os dados transmitidos, sendo por isso adequado para se trabalhar em redes inseguras. O shell a ser utilizado com o método ext é especificado pelo cliente. Se o cliente define a variável de ambiente $CVS_RSH , o valor dessa variável será usado para encontrar o executável do shell externo na máquina cliente. Se essa variável não for definida, o default é rsh (como esse default não traz o caminho completo, é preciso que rsh esteja no $PATH do cliente). Já no servidor, é preciso que o shell externo possa encontrar o executável do CVS. Para isso, basta que cvs esteja no $PATH do servidor (esta variável pode ser, por exemplo, definida no arquivo .bashrc ) ou que o cliente defina uma variável de ambiente $CVS_SERVER , apontando para o executável cvs . Versões mais novas do CVS permitem que $CVS_RSH e $CVS_SERVER sejam definidos na especificação do repositório, mas usar as variáveis é mais conveniente. Para que o método ext funcione corretamente, o shell escolhido deve estar instalado tanto no cliente quanto no servidor e o usuário deve ser capaz de conectar no servidor usando diretamente esse shell. É uma boa prática testar o acesso direto pelo shell antes de tentar utilizar o CVS. Como o shell é usado na conexão, quaisquer requisitos dele devem ser respeitados. Por exemplo, para o rsh , é preciso existir um arquivo .rhosts no diretório home do usuário no servidor, autorizando conexões do usuário cliente a partir da máquina cliente. Já para o ssh , é preciso gerar as chaves para a criptografia da conexão, para que o servidor não peça senha no momento da conexão. Como o servidor CVS é disparado pelo shell remoto, ele executa sob o login do usuário no servidor, com suas credenciais e permissões.
  • Os métodos gserver e kserver são usados para permitir autenticação Kerberos com o CVS. Enquanto o método kserver usa uma versão mais antiga, Kerberos 4, gserver usa a versão 5, que implementa a GSS-API. Esses método são pouco convenientes, pois precisam que o CVS seja recompilado para habilitar seu uso. Além disso, é preciso que o CVS seja disparado como um processo no servidor (um daemon no UNIX ou serviço no Windows) para escutar conexões dos clientes. Por esses motivos, os métodos gserver e kserver raramente são usados em novas instalações do CVS; eles só se justificam se a empresa já tem uma política interna de uso do sistema Kerberos.
  • O pserver é um método de conexão cliente/servidor simples e conveniente, mas pouco seguro. Ele é suportado diretamente pelo CVS, sem necessidade de recompilação ou instalação de outros aplicativos. Com ele, é possível acesso anônimo, acesso sem o uso de senhas e acesso para somente leitura. Por outro lado, ele é adequado apenas para uso interno a redes seguras, protegidas por firewall, pois não permite criptografia dos dados transmitidos e armazena as senhas no servidor usando uma codificação bastante trivial. Para repositórios que serão acessados por uma rede potencialmente insegura, o recomendado é utilizar o método ext com SSH. Para receber conexões pelo método pserver , é preciso que um processo esteja ativo no servidor (um daemon ou serviço, assim como nos métodos gserver e kserver ). A configuração desse processo depende do sistema operacional em uso no servidor mas, no caso de sistemas UNIX, envolverá a edição do arquivo inetd.conf . No próximo lab, em uma parte opcional, configuraremos um servidor para acesso pserver . Para invocar comandos usando pserver , o cliente deve antes executar o comando login . Este comando é bem simples, não recebe parâmetro algum e apenas usa a especificação do repositório (opção –d , ou $CVSROOT ) para executar o login . Uma vez autenticada aquela sessão, o cliente pode executar quaisquer comandos sobre o mesmo repositório. Ao terminar a interação com o servidor, o cliente deve finalizar a sessão com o comando logout , que possui o mesmo formato que login .
  • Neste lab, configuraremos o CVS para acesso remoto a repositórios. Preparamos o acesso pelo método ext com o SSH, a configuração mais recomendada para implantações distribuídas. Opcionalmente, testaremos o acesso pelo método pserver , uma alternativa útil para redes locais e seguras e que normalmente já vem configurado nas distribuições Linux.
  • O servidor CVS é configurado por dois mecanismos: arquivos administrativos e variáveis de ambiente. Já vimos que os arquivos administrativos são aqueles que se encontram no repositório, sob o diretório CVSROOT . Também já vimos como podemos editar esses arquivos: basta realizar um check-out de CVSROOT , editá-los em uma cópia local e submeter as modificações. No Lab2-2 vimos também que o CVS guarda uma cópia da última revisão desses arquivos juntamente com seus históricos e é essa cópia que governa o comportamento do CVS. Vimos também como controlar adequadamente as permissões sobre os arquivos administrativos. Outra informação importante sobre esses arquivos é que eles se aplicam a todo o repositório: todos os projetos são afetados por eles, assim como todos os usuários que se conectam ao repositório. Veremos que variáveis de ambiente também podem configurar alguns aspectos do comportamento do servidor. O detalhe mais importante sobre essas variáveis é que, ao contrário do que possa parecer, elas devem ser definidas no ambiente do cliente CVS. Quando o CVS funciona em modo local, isso é claro, pois é o próprio cliente que acessa o repositório. Mas tal fato parece estranho quando pensamos no funcionamento cliente/servidor. O que ocorre é que o cliente CVS lê essas variáveis do ambiente do usuário final e as passa como parâmetros ao servidor, que ajusta seu comportamento de acordo com esses valores. Como conseqüência, o usuário final do CVS (por exemplo, um programador) consegue configurar alguns comportamentos do servidor e, logo, cada usuário pode imprimir suas preferências a esses comportamentos.
  • A configuração default de arquivos administrativos, criada pelo comando init ao se criar um repositório atende a grande parte das necessidades de projetos, equipes e empresas. Entretanto, alguns comportamentos interessantes e às vezes necessários podem ser obtidos editando-se os arquivos administrativos. Não passaremos por todos os arquivos administrativos neste treinamento, mas veremos somente os principais, os mais comumente utilizados. O principal arquivo administrativo e também o mais frequentemente editado, é modules , que já vimos em um lab. Ele lista os módulos presentes no repositório. Veremos adiante sua sintaxe e como utilizá-lo corretamente. Outros arquivos importantes são cvsignore e cvswrappers , que definem padrões de arquivos que são automaticamente ignorados e filtrados pelo CVS, respectivamente. A configuração dada por esses arquivos afeta todo o repositório; é possível que usuários especifiquem seus próprios padrões, alterando somente o comportamento de seus clientes. O arquivo config define configurações variadas do repositório, enquanto que commitinfo , verifymsg e loginfo definem gatilhos executados no momento de um check-in, permitindo incrementar esse processo.
  • O arquivo administrativo modules é o mais importante e mais utilizado. Ele lista projetos (módulos) que se encontram no repositório. Na realidade, não é necessário que um projeto esteja listado em modules para que ele seja visível e possa ser obtido por check-out. Vimos isso ao trabalhar com os próprios arquivos administrativos, que se encontram sob CVSROOT : o diretório CVSROOT não se encontra listado em modules. As vantagens de se usar modules são: 1) os projetos nele incluídos são exibidos pelo comando checkout quando invocado com a opção –c ou –s , é possível atribuir um status descritivo ao projeto, que é exibido quando se usa –s; 2) modules permite a definição de módulos especiais, como veremos adiante. Cada linha de modules é uma definição de um módulo. Há 3 tipos diferentes de módulos. Um módulo normal é definido por seu nome, uma lista de opções, o nome do subdiretório, relativo à raiz do repositório, correspondente ao módulo, e uma lista opcional de arquivos sob esse subdiretório. Se um ou mais arquivos forem informados, o módulo incluirá somente esses arquivos. O exemplo mais comum desse tipo de definição é: lugares lugares Essa linha define um módulo chamado lugares , apontando para um diretório de mesmo nome sob a raiz do repositório. Outro tipo de módulo é o alias, que faz referência outros módulos ou subdiretórios, funcionando como um apelido. Este tipo de definição permite uma sofisticação: excluir subdiretórios. Isso pode ser feito colocando os diretórios a serem excluídos precedidos de “!” antes do nome dos módulos apelidados. Por fim, outro tipo de definição é a inclusão de módulos. A definição: modulo-geral &modulo1 &modulo2 Faz com que a área de trabalho seja criada sob um diretório modulo-geral, tendo com subdiretórios modulo1 e modulo2, ambos com o conteúdo dos diretórios correspondentes no repositório.
  • As opções permitidas na definição de um módulo normal são: – d outro_nome , que faz com que o diretório da área de trabalho seja criado com outro_nome , – e programa , que especifica um programa a ser executado sempre que o módulo for exportado, – o programa , idem para quando for feito um check-out do módulo, – t programa , idem para quando uma etiqueta for aplicada pelo comando rtag e – s status , que atribui um status ao módulo.
  • Como vimos no início do treinamento, alguns arquivos nunca serão colocados sob o controle de versões, tais como resultados de compilação, temporários, back-ups e atalhos. Os comandos CVS, tais como update , inspecionam a cópia de trabalho e listam os arquivos que não estão sob o controle de versões. Mas não queremos ser distraídos por esse tipo de arquivo, pois eles podem nos esconder os arquivos que realmente interessam. De forma similar, o comando import não deve nunca colocar esses arquivos sob o controle de versões. O mecanismo que o CVS oferece para evitar que esses arquivos apareçam na saída de comandos ou sejam importados por engano é pelos chamados “arquivos ignorados”. No lab onde importamos projetos para o CVS, usamos a opção –I para especificar padrões de nomes de arquivos que deviam ser ignorados por import . O arquivo administrativo cvsignore funciona da mesma forma, porém, os padrões nele especificados se aplicam a todos os comandos executados sobre o repositório, por qualquer usuário. O CVS já ignora alguns padrões por default, muito direcionados para o ambiente UNIX e para a programação em C. A lista de padrões ignorados por default é a seguinte: 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 Os padrões listados em cvsignore complementam essa lista. Como veremos adiante, é possível também que um usuário adicione mais padrões a essa lista, usando um arquivo pessoal chamado .cvsignore (note o “ . ” no início do nome), a variável de ambiente $CVSIGNORE e a opção –I , que já conhecemos. Para o desenvolvimento de sistemas em Java é conveniente coloca em cvsignore padrões como .class , .war e .ear .
  • O CVS permite o controle de algumas configurações de arquivos com base em padrões de nome. Por exemplo, é possível especificar que todos os arquivos terminados em .doc devem ser tratados como binários. O arquivo administrativo cvswrappers permite a definição dessas configurações para todo o repositório. Na terminologia do CVS, tais configurações são chamadas de wrappers , ou embaladores. O arquivo cvswrappers é organizado em linhas. Cada linha especifica um padrão de nome e sua configuração. O formato é: padrão [ opção valor ]... São duas as características que podem ser configuradas por cvswrappers . A primeira é o tratamento de palavras-chave, recurso do CVS que citamos ao final da introdução. O CVS tenta expandir palavras-chave que apareçam entre “ $ ” nos arquivos. A opção –k controla essa característica, juntamente com a opção de conversão de fins-de-linha. Os valores mais comuns passados para –k são: b para arquivos binários, que não devem sofrer expansão alguma, nem ter fins de linha convertidos; kv , que substitui as palavras-chave por seu nome e valor ( $Revision$ expande para $Revision: 1.4$ ); o , que preserva as palavras-chave, sem expansão alguma. A outra característica controlada por cvswrappers é a estratégia de mescla de arquivos: o valor MERGE indica que o CVS tentará realizar a mescla, enquanto que COPY faz com que o CVS não tente a mescla, mas crie duas cópias na área de trabalho, uma para cada revisão envolvida no conflito. Arquivos binários são COPY por default. O exemplo abaixo mostra um exemplo. *.jar -k b test-*.dat -m COPY –k o Esse exemplo indica que arquivos .jar devem ser considerados binários. Já arquivos iniciados por test- e com extensão .dat devem ser considerados texto, mas não devem ter substituição de palavras-chave e não devem sofrer mesclas automáticas. Um usuário pode definir embaladores exclusivos para seu ambiente de trabalho no arquivo de configuração pessoal .cvswrappers , ou ainda na linha de comando, com a opção –W , como vimos no comando import .
  • O arquivo administrativo config é um grande apanhado de configurações do repositório CVS. Como ele mudou bastante nas últimas versões do CVS, é recomendável consultar a documentação da versão em uso para conhecer sua sintaxe e as opções permitidas. Dentre as configurações normalmente permitidas por config , estão: especificar onde serão criados os arquivos de travas (leitura e escrita); controlar que comandos serão registrados no arquivo history , que armazena o histórico de atividades do repositório; configurar o cliente para que ele crie os diretórios CVS em uma árvore à parte e não dentro dos diretórios de trabalho e fazer com que o servidor pserver procure usuários na base de usuários do sistema operacional do servidor, caso eles não sejam encontrados no arquivo administrativo passwd .
  • O CVS oferece alguns “ganchos” para que o comportamento de alguns comandos possa ser configurado por programas externos. Já vimos as opções que podem ser incluídas no arquivo modules, permitindo que programas sejam executados durante comandos como checkout , export e rtag . Alguns arquivos administrativos permitem a configuração de mais alguns desses ganchos. Os arquivos mais utilizados para este propósito são os chamados “arquivos de suporte ao check-in”. Eles são 3: commitinfo , que especifica programas para validar novas revisões submetidas ao repositório por commit , verifymsg , que permite verificar as mensagens de log enviadas por commit , e loginfo , que especifica programas para pós-processar as mensagens de log de commit . O formato desses arquivos também é bastante similar. Todos são orientados por linhas, no seguinte formato: expressão_regular programa [ argumentos ... ] Cada linha contém uma expressão_regular seguida de uma linha de comando (um programa com argumentos opcionais). Quando um check-in é realizado, o arquivo-alvo da operação é comparado com cada expressão regular e, se há um casamento, o comando na mesma linha é executado. As expressões regulares especiais DEFAULT e ALL podem ser utilizadas. A expressão DEFAULT é um casamento se nenhuma outra expressão regular for selecionada. A linha contendo a expressão ALL é sempre selecionada, mesmo que outra expressão regular (incluindo DEFAULT ) tenha sido selecionada. Neste caso, mais de um comando será executado; caso contrário, apenas a primeira linha com casamento é executada. Outros arquivos similares em sintaxe são taginfno, que especifica programas para serem executados quando etiquetas são aplicadas pelo comando rtag , e rcsinfo que não configura nenhum programa a ser executado, mas informa o caminho para um template a ser usado para formatar a mensagem de log de commit .
  • Como já vimos em algumas situações, o comportamento do CVS é influenciado por diversas variáveis de ambiente. Este slide lista as principais variáveis que afetam o comportamento do CVS. Considerando o funcionamento cliente/servidor, elas são lidas no ambiente do cliente e algumas têm seus valores são passados para o servidor. A exceção é a variável $PATH , consultada diretamente no servidor para encontrar o executável do CVS nos métodos ext , pserver e fork .

Transcript

  • 1. Administração do CVS Módulo 2 Foco: Administrador de Sistemas
  • 2. Agenda
    • Planejando a capacidade para o CVS
    • Escolhendo a distribuição mais adequada
    • Instalando o CVS, de binários e de fontes
    • Criando e conhecendo melhor os repositórios
    • Criando e importando projetos
    • Copiando, movendo e apagando repositórios
    • Controlando acessos e permissões
    • Configurando o comportamento do CVS
  • 3. Planejamento de Capacidade
    • O CVS é um sistema cliente/servidor
      • Um planejamento para sua implantação deve levar em conta ambas as partes, bem como sua comunicação
    • Podemos descartar a necessidade de planejamento de capacidade para o cliente CVS
      • É muito leve, qualquer estação de trabalho é capaz de executá-lo
      • Muitos IDEs modernos já trazem o cliente embutido
    • O planejamento de capacidade do servidor pode ser dividido em 4 aspectos (em ordem de relevância):
      • Armazenamento
      • Rede
      • Memória
      • Processamento
  • 4. Armazenamento
    • Planejar o armazenamento para o CVS equivale a estimar o tamanho do repositório, ou seja, dos históricos
    • Para isso existem 3 fatores a serem considerados, em relação aos arquivos sob controle de versões:
      • Tamanho dos arquivos
      • Freqüência de alteração
      • Tipo dos arquivos (texto ou binário)
    • Antes de detalhar cada fator, vejamos como o CVS organiza seus arquivos de histórico:
      • Para arquivos de texto, os históricos guardam somente as diferenças entre as revisões
      • Para binários, cada revisão é mantida integralmente nos históricos
  • 5. Tamanho dos Históricos
    • Obviamente, quando maiores os arquivos, mais espaço eles ocuparão no repositório
    • Cada arquivo evolui em velocidade decrescente até atingir uma razoável estabilidade
      • Isso quer dizer que, com o passar do tempo, seu histórico cresce cada vez menos
      • Podemos associar a curva de crescimento de um histórico típico à função logaritmo (próximo slide)
    • A questão a ser respondida é: Como estimar o tamanho de estabilidade de um histórico?
      • Assumindo que sabemos o tamanho do arquivo em si
  • 6. Crescimento dos Históricos
  • 7. Calculando o Tamanho dos Históricos
    • Tomando estatísticas sobre projetos, criamos algumas “regras do dedão”
    • Dado o tamanho F (talvez estimado) do arquivo, o tamanho H de seu histórico é dado por:
      • Para arquivos texto: H = 3 F
      • Para arquivos binários: H = 5 F
    • É razoável assumir que F é dado
      • Para projetos importados, ele é conhecido, basta verificar o tamanho dos fontes
      • Para novos projetos, os programadores podem estimá-lo com base em projetos anteriores
  • 8. Projetando o Armazenamento
    • A principal recomendação é usar o bom senso na aquisição do equipamento
      • Os cálculos ajudam, mas lembrem que os históricos demoram para atingir a estabilidade
    • A capacidade de armazenamento pode começar menor e crescer ao longo do projeto
      • Escolha uma ocupação máxima (p.e., 80%) e, ao alcançá-la, aumente a capacidade
      • A movimentação de repositórios é uma tarefa relativamente simples, assim como o back-up
    • Os maiores vilões são os arquivos binários
      • Normalmente são maiores e seus históricos crescem mais rápido
      • Por sorte, muitos deles não devem ficar sob o controle de versões!
  • 9. Rede
    • O planejamento da rede leva em conta 2 fatores:
      • O tamanho total do projeto (arquivos, não históricos)
      • A taxa de acessos ao repositório, que depende do número de programadores envolvidos no projeto
    • Como vimos, o 1o fator pode ser estimado
    • Para analisar o 2o fator, façamos considerações:
      • Cada programador trabalha a maior parte do tempo em sua área de trabalho e a atualiza algumas vezes ao dia
      • Quando uma atualização é feita:
        • O CVS verifica o timestamp do arquivo local
        • Se ele for diferente do momento da última atualização, o CVS faz uma comparação para identificar diferenças, no servidor
  • 10. Projetando a Capacidade de Rede
    • Mais uma “regra do dedão”:
      • Dado M , o tamanho total do módulo
      • Cada dia, cada programador gera:
        • 0,5 M bytes de tráfego do cliente para o servidor
        • 1,5 M bytes de tráfego do servidor para o cliente
    • A regra é uma grande simplificação
      • Assume que cada programador trabalha em um projeto
      • Não estima picos de tráfego
    • Dicas para racionalizar o consumo de rede:
      • Mantenha relógios de clientes e servidor em sincronia
      • Recomende o uso do parâmetro –z nos clientes
  • 11. Memória
    • Memória dificilmente será um problema
      • O CVS tem mais de 15 anos, portanto, é econômico para os padrões atuais
    • Outra regra:
      • O consumo máximo de memória será 10x o tamanho do maior arquivo
    • Onde podem surgir problemas:
      • Muitos programadores acessando o servidor ao mesmo tempo: o CVS cria um processo para cada cliente
      • Módulos muito grandes: o check-out será pesado
      • Arquivos muito grandes: comandos como diff carregam todos os dados em memória
  • 12. Processamento
    • É a menor das preocupações
      • O CVS foi criado quando processadores de 33MHz eram considerados rápidos
    • A regra:
      • Qualquer máquina que puder ser chamada de “servidor” comportará o servidor CVS
      • Procure não colocar muitos outros serviços na máquina
    • A arquitetura da máquina é mais importante que o processador
      • Um barramento rápido e um I/O eficiente farão a diferença
  • 13. Instalando o CVS
    • Passo 1: Definir o sistema operacional
      • UNIX ou Windows
    • Passo 2: Escolher uma distribuição
      • GNU CVS ou CVSNT
    • Passo 3: Compilar a distribuição (opcional)
      • Caso se tenha optado por uma distribuição-fonte
    • Passo 4: Instalar a distribuição
      • Manualmente ou usando um instalador
    • Passo 5: Conferir a instalação
      • Executar o CVS e testar alguns comandos
  • 14. Definindo o Sistema Operacional
    • É mais uma questão de política da empresa do que uma necessidade do CVS
      • Hoje, tanto servidor quanto clientes podem ser instalados em UNIX, Windows e até Macintosh
    • O mais importante é escolher o servidor levando em conta a demanda de acesso a disco e rede
    • Entretanto, há algumas restrições:
      • Escolhendo o Windows como servidor, é recomendável optar pela distribuição CVSNT; as versões possíveis são NT, 2000 e XP
      • Caso se opte pelo uso de SSH para se ter conexões seguras entre cliente e servidor, versões compatíveis de SSH devem ser usadas
      • Com clientes em múltiplas plataformas, os programadores devem ficar atentos às quebras de linha em seus editores
  • 15. Escolhendo uma Distribuição
    • As duas distribuições do CVS são:
      • GNU CVS: a distribuição original do CVS, de código aberto (licença GPL) e mantida pela FSF
      • CVSNT: uma derivação do GNU CVS, também GPL, mantida pela empresa March-Hare
        • Suporte comercial e treinamento são oferecidos
    • Ambas podem ser instaladas em Windows e Linux
      • A instalação do servidor e do cliente é a mesma
    • A recomendação é:
      • Em clientes UNIX/Linux: utilizar o GNU CVS
      • Em clientes Windows e Macintosh: utilizar o CVSNT
      • Para o servidor CVS: usar UNIX/Linux com o GNU CVS
  • 16. Qual Versão Instalar?
    • Optando pelo GNU CVS, há duas opções:
      • Versões stable : estão em uso há bastante tempo, sem grandes evoluções recentes ou novas funcionalidades
        • Atualmente, as versões estáveis estão sob o número 1.11
        • A última versão estável do GNU CVS é a 1.11.21
      • Versões feature : introduzem novos recursos ou melhorias arquiteturais
        • Atualmente, as novas versões evolutivas estão sob 1.12
        • A última versão evolutiva do GNU CVS é a 1.12.13
    • Optando pelo CVSNT:
      • A versão paga (CVS Suite) está na versão 2.5.02
      • A versão open-source está na versão 2.5.03
  • 17. Instalação e Verificação
    • É recomendado instalar uma distribuição binária
      • Compilar uma distribuição-fonte só se justifica em situações muito específicas
    • A instalação do CVS é uma tarefa muito simples
      • Em qualquer distribuição ou sistema operacional, é possível usar um instalador
      • Faremos a instalação (Linux e Windows) no próximo lab
    • Para conferir a instalação:
      • cvs –v : mostra a versão instalada localmente
      • cvs version : mostra as versões do cliente local e do servidor, se um servidor remoto estiver em uso
  • 18. Lab2-1: Instalando o CVS
    • Instalar o CVS no Linux
      • Compilar a distribuição GNU CVS em código-fonte
      • Instalar a distribuição binária do GNU CVS
    • Instalar o CVS no Windows
      • Instalar a distribuição binária do CVSNT
    • Testar a Instalação
      • Verificar a instalação local
      • Verificar a instalação do servidor
      • Usar o comando version
  • 19. Localização do Repositório
    • O repositório é um diretório especial contendo históricos
      • Ao menos um repositório deve estar disponível para o uso do CVS
    • O ideal é cada programador trabalhar em um repositório
      • Boa prática: criar um repositório por empresa ou departamento
    • Um repositório pode ser criado em qualquer disco local no servidor CVS, com algumas observações:
      • A área escolhida deve preferencialmente ter back-ups diários
      • O sistema de arquivos escolhido não pode travar o servidor se atingir sua capacidade máxima
      • Em sistemas UNIX, um local comum é /var/lib/cvs
      • Em sistemas Windows, pode-se optar por D:cvs
    • Crie um usuário para ser o dono de todo o repositório
      • Garanta que ele é o dono da raiz do repositório
    • Trate o servidor CVS como um servidor de arquivos!
  • 20. Criando um Repositório
    • Um repositório é criado pelo comando init
      • Este comando cria um diretório no local especificado, com a configuração padrão de um repositório
    • O local de criação do repositório é especificado pela opção global -d ou pela variável $CVSROOT
      • É a mesma forma que usamos para especificar a localização do repositório para o comando checkout
    • Com init , é mais comum usar-se a opção -d
      • Nem é recomendável para o administrador de sistemas definir a variável $CVSROOT em seu ambiente
    • Não há perigo se init for chamado especificando-se um repositório existente (nada é sobrescrito)
  • 21. O Comando init
    • O comando init cria um repositório
    • cvs [ op_glob ] init
      • op_glob são opções globais do CVS. A única opção que afeta init é –d , que dá a localização do repositório
    • Ele não recebe argumentos e, se a opção –d não for especificada, usa a variável $CVSROOT
  • 22. Lab2-2: Criando um Repositório
    • Criar um repositório com o comando init
    • Examinar os arquivos criados no repositório
    • Fazer o check-out do diretório CVSROOT
    • Alterar um arquivo na cópia de trabalho
    • Submeter uma alteração em um arquivo administrativo
  • 23. A Estrutura do Repositório
    • É mera curiosidade saber como as informações são armazenadas em um repositório
      • Todos os acessos devem ser feitos pelos comandos CVS, pois o formato interno do repositório pode mudar
    • Um repositório CVS é um diretório comum, contendo, em um primeiro nível:
      • Um diretório CVSROOT , contendo arquivos administrativos (de configuração e controle)
        • Inclui históricos e as cópias mais recentes desses arquivos
      • Zero ou mais diretórios, correspondendo a módulos (projetos) sob o controle de versões
        • Cada subdiretório de um módulo inclui os históricos dos arquivos correspondentes (mesmo nome, seguido de ,v )
  • 24. Criando Projetos no CVS
    • Na terminologia do CVS, projetos e módulos são sinônimos
      • Conceitualmente, são unidades independentes de trabalho, como programas, projetos, artigos, sites
      • Para o CVS, são diretórios sob a raiz do repositório
    • Para criar um projeto no CVS é preciso importá-lo
      • Esta tarefa cabe em geral ao gestor de configuração
    • Preparação
      • Crie um conjunto inicial de arquivos para a importação
      • Organize-os em uma estrutura quase definitiva de diretórios
    • Importação
      • Execute o comando import , para popular o repositório
    • Declaração (opcional)
      • Edite o arquivo modules , incluindo a declaração do módulo
  • 25. O Comando import
    • O comando import cria um novo projeto ou atualiza arquivos fornecidos por terceiros
      • Deve ser executado de dentro do diretório onde se encontram os arquivos a importar
    • cvs [ op_glob ] import [ op_cmd ] nome_projeto ramo_fornec etiq_versão ...
      • op_glob e op_cmd são opções globais e do comando
      • nome_projeto é o nome do projeto a ser criado
      • ramo_fornec é o nome do ramo do fornecedor dos arquivos; as revisões criadas ficarão sob esse ramo
      • etiq_versão ... são uma ou mais etiquetas a serem aplicadas sobre as revisões criadas, marcando a versão
  • 26. Lab2-3: Importando Projetos
    • Importar um conjunto de arquivos para o CVS, criando um novo projeto
    • Importar um novo conjunto de arquivos do mesmo fornecedor para o mesmo módulo
    • Alterar um arquivo do projeto e importar novamente, causando um conflito
    • Entender o funcionamento das opções de arquivos ignorados e filtrados
  • 27. Importando de Outros SCVs
    • Ao migrar para o CVS, o ideal é importar os arquivos mantendo seus históricos
    • A forma geral para se importar históricos para o CVS é através de arquivos RCS
      • Basta criar um diretório para o projeto no repositório e copiar os arquivos RCS para ele
    • Há scripts disponíveis para exportar arquivos RCS
      • SCCS: usar o script sccs2rcs na distribuição GNU CVS
      • PVCS: usar o script pvcs_to_rcs no GNU CVS
      • Outros sistemas podem disponibilizar seus conversores
    • Em último caso, a opção é importar as últimas revisões e algumas liberações mais relevantes
  • 28. Gerenciando Back-ups
    • Um repositório CVS é uma árvore de diretórios
      • Back-ups podem ser feitos com as mesmas ferramentas utilizadas para outras áreas de dados
      • É importante que estrutura, propriedades, permissões e outros atributos sejam mantidos como no original
    • As seguintes atividades estão relacionadas à gerência de back-ups de um repositório CVS
      • Congelar o repositório: pré-requisito para efetuar a cópia do repositório
      • Copiar os dados: criar uma foto do repositório
      • Restaurar um back-up: voltar a um estado anterior
      • Espelhar um repositório: replicar os dados para leitura
  • 29. Congelando um Repositório
    • Significa impedir que usuários modifiquem o repositório
      • Visa garantir que uma cópia encontre todos os dados em um estado consistente
      • Caso isso não seja feito, uma cópia pode ser feita em meio a um check-in de vários arquivos
    • Há diversas alternativas para atingir esse objetivo
      • Desligar o processo servidor do CVS
      • Impedir logins no servidor (ou deixá-la em modo single user )
      • Bloquear o servidor com um firewall (ou desligar a rede)
      • Travar o repositório no modo exclusivo para leitura
    • Travar o servidor é a forma preferida
      • Permite que usuários continuem usando o servidor para leitura
      • Os materiais do aluno incluem scripts para congelar e descongelar
  • 30. Criando e Restaurando Back-ups
    • Uma vez congelado o repositório, uma cópia pode ser criada usando uma ferramenta de back-up
      • Todos os atributos devem ser preservados, para manter as configurações de segurança do repositório
      • Exemplo de ferramenta simples e acessível: tar
    • Para restaurar um back-up:
      • Certifique-se que os atributos serão preservados
      • Congele totalmente o repositório durante a restauração
      • Garanta que o diretório CVSROOT foi restaurado; os projetos podem ser restaurados em qualquer ordem
      • Peça que usuários façam novo check-out de seus projetos e refaçam mudanças pendentes
  • 31. Espelhando um Repositório
    • Muitos projetos têm cópias públicas disponíveis
      • Projetos open-source de instituições como FSF, Apache
    • As cópias devem permitir somente leitura
      • CVS não trata modificações em diferentes repositórios
    • Os repositórios-espelho podem estar desde na mesma máquina até em uma rede distante
    • O processo de espelhamento é similar ao back-up
      • Congele o repositório original (permita somente leitura) e o destino (totalmente)
      • Faça a cópia usando uma ferramenta (ex.: rsync )
      • Descongele ambos os repositórios
  • 32. Editando um Repositório
    • Editar um repositório significa realizar uma das seguintes operações:
      • Mover ou apagar todo um repositório
      • Mover ou apagar um módulo
      • Mover ou apagar arquivos e diretórios em um módulo
    • As operações listadas têm diferentes motivações
      • Move-se um repositório para colocá-lo em uma partição de um novo disco, ou em uma área com back-up
      • Move-se um módulo quando se muda de idéia sobre seu nome
      • Move-se um arquivo ou um diretório quando o projeto demanda essa alteração
      • Remove-se qualquer um dos itens listados quando ele não está mais em uso
  • 33. Movendo e Apagando Repositórios
    • Mover um repositório é similar a criar um back-up e depois restaurá-lo
      • Congele o repositório
      • Copie os arquivos para a nova área, mantendo atributos como propriedade, permissões e datas de alteração ( cp –a )
      • Peça para que os usuários alterem suas variáveis $CVSROOT , façam check-outs do novo repositório e refaçam alterações
    • Antes de remover um repositório certifique-se do que está fazendo
      • Faça um back-up dos dados (nunca se sabe!)
      • Verifique se há scripts usados pelos arquivos administrativos repositório e que podem ser removidos
      • Remova recursivamente a raiz do repositório
        • Por exemplo: rm –rf /var/lib/cvs
  • 34. Movendo e Apagando Módulos
    • Há duas opções para mover (renomear) um módulo:
      • Mover o diretório correspondente ao módulo
        • Alternativa mais radical; o nome original não é mais acessível
        • Invalida as áreas de trabalho dos usuários
      • Definir o novo módulo no arquivo modules
        • Opção mais moderada, não necessita acesso direto ao servidor
        • O nome original do módulo continua acessível, cópias de trabalho antigas continuam válidas
    • Ao remover um módulo, antes faça um back-up
      • Verifique se há referências ao diretório em modules
      • Remove recursivamente o diretório do módulo
  • 35. Movendo Arquivos
    • O CVS permite adicionar e remover arquivos com add e remove , mas não tem um comando para mover arquivos
    • Há 3 alternativas para isso:
      • Renomear o arquivo na área de trabalho, remover do repositório e então adicionar, usando remove e add
        • É simples, não requer acesso privilegiado ao repositório, liberações são preservadas, mas o histórico é interrompido
      • Renomear o arquivo de histórico no repositório ( mv )
        • Preserva as revisões no histórico do arquivo, mas requer acesso shell ao repositório e pode danificar liberações anteriores
      • Copiar o arquivo antigo para criar o novo e mover o antigo para o Attic , como uma revisão morta
        • Preserva as revisões no histórico e liberações antigas, mas é bem mais complexo e pode levar a problemas com ramos
  • 36. Movendo e Apagando Diretórios
    • Ao contrário de arquivos, o CVS não possui comandos para manipular diretórios
    • Um diretório é adicionado ao repositório se algum arquivo debaixo dele for adicionado
    • Para apagar um diretório, remova todos seus arquivos
      • Fazendo isso, o diretório vazio continua sendo visto; evita-se isso com a opção –P em checkout e update
    • Para mover um diretório há 3 formas:
      • Mover todos os arquivos para o novo nome na cópia local, removê-los do local antigo no repositório e adicionar os “novos” arquivos
      • Renomeá-lo diretamente no repositório
      • Copiá-lo para o novo nome no repositório e depois remover todos os arquivos sob o nome antigo a partir de uma área de trabalho
  • 37. Segurança no CVS
    • A segurança de projetos sob controle de versões no CVS depende dos seguintes aspectos:
      • A área de armazenamento do repositório
      • O servidor CVS e seu ambiente
      • Todos os computadores contendo áreas de trabalho
      • Os métodos de acesso ao repositório
      • O armazenamento dos back-ups
    • A segurança do servidor, das estações de trabalho e dos back-ups é comum a qualquer ambiente
    • Destacaremos questões relativas às permissões no repositório e aos métodos de acesso
  • 38. Controlando Permissões
    • A segurança do armazenamento do repositório depende das permissões do sistema de arquivos
      • É dependente do sistema operacional no qual o servidor executa
      • Discutiremos as configurações para um servidor UNIX
    • Raiz do repositório
      • Apenas os usuários que podem criar projetos devem ter permissão de leitura, escrita e execução; os demais, leitura e execução
      • Deve ter o bit SGID ligado
    • Diretório CVSROOT
      • Todos usuários devem ter acesso de leitura a todos os arquivos e permissão de escrita aos arquivos history e val-tags
      • Só usuários avançados podem ter acesso de escrita aos demais arquivos (administrador de sistemas e gestor de configuração)
  • 39. Permissões em Projetos
    • Só é possível controlar permissões no nível de diretórios
      • Quando se faz um check-in, o CVS cria uma cópia temporária do histórico e depois a joga sobre o original
      • Consequentemente, permissões são sobrescritas e o dono é trocado a cada nova revisão de um arquivo
    • A segurança em projetos é garantida por grupos
      • Cada projeto deve ser propriedade de um grupo e as permissões dos diretórios devem refletir isso
        • Configuração geral: u=rwx, g=rwx, o=rx
      • O bit SGID também deve estar ativo
  • 40. Permissões de Somente Leitura
    • Para configurar permissões de somente leitura em um projeto, é preciso mudar o local de criação de travas
      • Por default, o CVS cria travas dentro do diretório do projeto
    • Como o CVS também cria travas para leitura, se o default for mantido, ocorrerá uma dos seguintes casos:
      • Se tirarmos a permissão de escrita do módulo para outros, impedimos a leitura por quem não é do grupo do projeto
      • Se dermos permissão de escrita no módulo para outros, quem não pertence ao grupo do projeto poderá alterar os arquivos
    • O arquivo que controla o local das travas é config
      • A propriedade a ser alterada chama-se LockDir
    • Para impedir a leitura de um projeto, deve-se tirar as permissões de leitura e execução de outros
  • 41. Lab2-4: Controlando Permissões
    • Criar um grupo e associá-lo a usuários e projetos
    • Configurar o repositório CVS para permitir acessos de somente leitura a um projeto
    • Testar a configuração, tentando check-outs e check-ins com usuários dentro e fora do grupo
    • (Opcional) Configurar um projeto para não permitir a leitura por usuários fora de seu grupo
  • 42. Repositórios Locais e Remotos
    • O CVS opera com repositórios locais ou remotos
      • No primeiro caso, ele funciona como um programa independente, no segundo, como cliente/servidor
    • Quando optar pelo uso local?
      • Em um projeto particular
      • Com uma equipe usando um único servidor por terminais
    • E o uso remoto?
      • Em projetos distribuídos
      • Com equipes onde cada um usa sua própria estação de trabalho
  • 43. Métodos de Acesso Remoto
    • Como vimos no módulo introdutório, um repositório pode ser especificado no formato:
      • [: método :][ usuário [: senha ]@][ servidor [: porta ]] raiz
    • O elemento método pode ser um dentre:
      • local : para repositórios na máquina local
      • ext : método de conexão por shell externo, estilo rsh ou ssh
      • fork : para conectar na máquina local como se fosse remota
      • server : método de conexão rsh , interno ao CVS
      • gserver : conexões usando a GSS-API (Kerberos 5)
      • kserver : conexões usando Kerberos 4
      • pserver : conexões usando o servidor de senhas interno
    • Dependendo do método especificado, alguns dos outros elementos podem ser omitidos
  • 44. Os Métodos local e fork
    • São usados para acessar repositórios locais
    • Usar o método local é equivalente a especificar diretamente o caminho do repositório
      • – d :local:/var/lib/cvs é idêntico a –d /var/lib/cvs
    • O método fork força o CVS a funcionar no modo cliente/servidor, mas não usa a rede
      • Cliente e servidor executam sob o mesmo usuário: o processo servidor é um fork do cliente
      • É usado para depuração, ajudando a verificar se um problema está na rede ou no modo cliente/servidor
  • 45. Os Métodos ext e server
    • O método ext é um dos mais utilizados
      • Ele usa um shell externo para a conexão remota
      • Combinado com o SSH, é a opção para redes inseguras
    • Algumas configurações de variáveis de ambiente:
      • O executável do shell cliente deve ser especificado pela variável de ambiente $CVS_RSH , na máquina cliente
      • O executável do CVS deve estar no $PATH do servidor, ou o cliente deve apontar $CVS_SERVER para ele
    • O shell dispara o comando cvs no servidor com as permissões do usuário remoto que conectou
    • O método server é similar e usa um shell interno
      • Depende de um processo servidor: comando server
  • 46. Os Métodos gserver e kserver
    • O método gserver usa a GSS-API para permitir autenticação e criptografia da conexão CVS
      • Essa API apenas define uma interface, quem autentica e criptografa é outro sistema, tal como Kerberos 5
    • O método kserver usa diretamente Kerberos 4
      • Este sistema tem falhas que foram corrigidas na versão 5 e deve ser evitado em novas instalações do CVS
    • Servidor e cliente CVS devem ser recompilados para permitir o uso desses métodos
    • Um processo deve ser iniciado no servidor para receber conexões por pserver e kserver
      • Em sistemas UNIX, deve-se editar inetd.conf
  • 47. O Método pserver
    • Permite conexões com o repositório usando usuários e senhas armazenados no servidor
      • O administrador deve criar um arquivo passwd
    • O método pserver tem algumas vantagens
      • Já é automaticamente suportado pelo CVS
      • Permite acesso anônimo, sem senha e somente leitura
    • Há algumas desvantagens
      • A codificação das senhas no servidor é trivial
      • A comunicação cliente/servidor não é criptografada
    • Para receber conexões pserver , um processo deve ser iniciado no servidor ( inetd.conf )
    • Para invocar comandos pelo método pserver , o cliente deve antes executar login e, ao fim da sessão, logout
  • 48. Lab2-5: Configurando o Acesso Remoto
    • Testar a instalação do servidor SSH no Linux
    • Instalar um cliente SSH no Windows (PuTTY)
    • Testar a conexão cliente/servidor
    • Criar e configurar chaves pública e privada
    • Configurar $CVS_RSH e realiza um check-out usando o método ext
    • (Opcional) Realizar um check-out usando o método pserver
  • 49. Configurando o Servidor CVS
    • O comportamento do servidor é configurado por:
      • Arquivos administrativos
      • Variáveis de ambiente
    • Arquivos administrativos estão no repositório sob o diretório CVSROOT
      • São únicos por repositório; aplicam-se a todos os projetos e todos os usuários
    • Variáveis de ambiente são definidas pelo cliente
      • Quando o CVS funciona em modo cliente/servidor, elas são lidas pelo cliente e passadas para o servidor
      • Portanto, o usuário final é capaz de configurar alguns comportamentos do servidor
  • 50. Os Arquivos Administrativos
    • O CVS funciona satisfatoriamente sem que seja necessário editar os arquivos administrativos
    • Porém, alguns comportamentos avançados podem ser obtidos usando corretamente tais arquivos
    • Os principais arquivos administrativos são:
      • modules : lista os módulos presentes no repositório
      • cvsignore : especifica padrões de arquivos ignorados
      • cvswrappers : especifica padrões de arquivos filtrados
      • config : define configurações variadas do repositório
      • commitinfo , verifymsg , loginfo : definem gatilhos que configuram o processo de check-in
  • 51. O Arquivo modules
    • Lista projetos (módulos) presentes no repositório
      • Um projeto não precisa estar em modules para ser visível: basta que ele seja um subdiretório da raiz do repositório
    • Entretanto, incluir projetos em modules tem vantagens:
      • Os projetos listados em modules são exibidos pelo comando checkout , quando se usa –c ou –s
      • É possível definir módulos especiais ou excluir diretórios
    • Cada linha é uma definição de módulo:
      • Módulo normal: nome [ opções ] dir [ arquivos ...]
        • É possível especificar em dir um subdiretório qualquer do repositório
        • Se arquivos forem especificados, somente eles serão obtidos
      • Módulo alias: nome –a [! dir_excluído ] alias ...
        • É possível excluir diretórios precedendo-os por !
      • Inclusão de módulo: nome [ opções ] & módulo_inc...
        • Quando nome for obtido, ele terá um subdiretório módulo_inc
  • 52. Opções Permitidas em modules
    • Os módulos normais e com inclusão permitem as seguintes opções:
      • -d outro_nome : o diretório de trabalho terá outro_nome , não o nome do módulo
      • - e programa : programa será executado sempre que o módulo for exportado
      • -o programa : programa será executado sempre que foi feito um check-out do módulo
      • -t programa : programa será executado sempre que uma etiqueta for aplicada pelo comando rtag
      • -s status : define um status para o módulo. Este status é consultado por checkout , com a opção -s
  • 53. O Arquivo cvsignore
    • Alguns arquivos devem ser ignorados pelos comandos CVS, tais como import e update
      • Esses arquivos nunca serão colocados sob controle de versões e nem queremos que o CVS os veja
      • Exemplos: arquivos resultantes de compilação, temporários, arquivos de back-up, links (atalhos)
    • Padrões de nomes de arquivos que devem ser ignorados são listados em cvsignore
      • O CVS já oferece alguns padrões ignorados por default
    • Outros padrões podem ser especificados de outras formas
      • Arquivo .cvsignore , variável $CVSIGNORE , opção -I
  • 54. O Arquivo cvswrappers
    • O CVS permite que algumas configurações de arquivos sejam controladas de acordo com padrões de nome
    • Tratamento de palavras-chave: o CVS pode tentar expandir algumas palavras envolvidas por $
      • A opção –k controla se elas serão expandidas ou não
    • Metodologia de atualização: o CVS pode atualizar um arquivo usando diferenças ou uma cópia nova
      • A opção –m controla se será tentada a atualização por diferenças ou se será feita uma cópia da nova revisão
    • O arquivo cvswrappers especifica padrões e suas opções
    • O uso mais comum desse arquivo é listar padrões de nomes de arquivos binários, com a opção –k b
  • 55. O Arquivo config
    • O arquivo config é uma miscelânea de configurações do repositório CVS
    • Ele mudou bastante nas últimas versões do CVS
    • Algumas configurações que config permite:
      • Especificar o diretório onde as travas são criadas
      • Controlar o que é registrado no arquivo history , que armazena o histórico de atividade do repositório
      • Fazer com que os diretórios CVS das cópias de trabalho sejam criados em uma árvore de diretórios à parte
      • Permitir que o servidor pserver procure um usuário no sistema operacional se ele não estiver em passwd
  • 56. Os Arquivos de Suporte ao Check-in
    • Alguns arquivos administrativos configuram programas externos a serem executados
      • Os eventos que podem disparar tais programas são a aplicação de etiquetas e o check-in
    • Os arquivos de suporte ao check-in são:
      • commitinfo : especifica programas para validar a revisão submetida em um commit
      • verifymsg : especifica programas para verificar a mensagem de log de um commit (opção –m )
      • loginfo : especifica programas para pós-processar a mensagem de log de um commit
    • Outros arquivos similares: taginfo e rcsinfo
  • 57. Variáveis de Ambiente
    • Principais variáveis de ambiente vistas pelo CVS:
      • $CVSIGNORE , $CVSWRAPPERS : listam padrões de nomes de arquivos a serem ignorados e filtrados
      • $CVSREAD : se definida, checkout e update deixam os arquivos da área de trabalho read-only
      • $CVSEDITOR , $EDITOR , $VISUAL : configuram o editor invocado pelo CVS. São consultadas nesta ordem
      • $PATH : no cliente, usada para achar o shell para o método ext e no servidor, para o executável do CVS
      • $CVS_RSH : nome do executável do shell externo
      • $CVS_SERVER : nome do executável do CVS, invocado pelo processo servidor nos métodos ext , server e fork
      • $TMPDIR : diretório temporário usado pelo CVS