akabei 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 573c7770c6f4880b4805deecf432dd1d893435fa
4
- data.tar.gz: 5ba638d8e424de0d86b570ee3f4060d15100d08d
3
+ metadata.gz: a344960f6cb67186fdad797fd77c3608492d389d
4
+ data.tar.gz: 7106dcb7cb0a6fc65d6539ac9ba302beb55f33cd
5
5
  SHA512:
6
- metadata.gz: a89b4bdce9f46c869a90e255f07d124bd3f27bdea251de7593a5d93e938532b07aab9aea16f882148e5e684ef0576b65ac0db5e125d551c7350094cb4cb200a9
7
- data.tar.gz: b93ee03dffba2e814da2f38e6077b4fa4865776f658ada381af69df06afd7d1b165ddec623e34aab4a3755a0ef537b7c4aeafaf00fffa6145290f72c606758c4
6
+ metadata.gz: 2daaa37e0ad5630f907e06c4a48f469ba27370278ad7793f07faef74548379856f294b8846160e801e7dd511e7d6e390b0d12532905e42d82508e560cb31c57f
7
+ data.tar.gz: ed557ee39ea6985bd629b6530c187e4a9946cc2f066639806e8d8ac99440dbd919a433544dcd7f71eb39a4f48421dc30a3ae86218be68fb9fec6458d4d4d8bd2
@@ -0,0 +1,15 @@
1
+ # 0.2.0 (2014-01-19)
2
+ - Add omakase mode
3
+ - akabei omakase init
4
+ - akabei omakase init --s3
5
+ - akabei omakase build
6
+
7
+ # 0.1.0 (2014-01-17)
8
+ - Initial release
9
+ - akabei build
10
+ - akabei abs-add
11
+ - akabei abs-remove
12
+ - akabei files-add
13
+ - akabei files-remove
14
+ - akabei repo-add
15
+ - akabei repo-remove
data/README.md CHANGED
@@ -1,4 +1,5 @@
1
1
  # Akabei
2
+ [![Gem Version](https://badge.fury.io/rb/akabei.png)](http://badge.fury.io/rb/akabei)
2
3
  [![Build Status](https://secure.travis-ci.org/eagletmt/akabei.png)](https://travis-ci.org/eagletmt/akabei)
3
4
  [![Code Climate](https://codeclimate.com/github/eagletmt/akabei.png)](https://codeclimate.com/github/eagletmt/akabei)
4
5
  [![Coverage Status](https://coveralls.io/repos/eagletmt/akabei/badge.png)](https://coveralls.io/r/eagletmt/akabei)
@@ -46,6 +47,82 @@ foo-1.0.0.tar.gz
46
47
  foo-1.0.0-1-x86_64-build.log foo-1.0.0-1-x86_64-package.log
47
48
  ```
48
49
 
50
+ ## Omakase mode
51
+ Omakase mode supports a typical situation managing the custom repository.
52
+
53
+ ### Initialize a repository
54
+ `--repo-key` and `--package-key` are optional.
55
+
56
+ ```
57
+ % akabei omakase init foo --repo-key $GPGKEY --package-key $GPGKEY
58
+ create .akabei.yml
59
+ create foo
60
+ create sources
61
+ create logs
62
+ create PKGBUILDs
63
+ create etc
64
+ create etc/makepkg.i686.conf
65
+ create etc/pacman.i686.conf
66
+ create etc/makepkg.x86_64.conf
67
+ create etc/pacman.x86_64.conf
68
+ Edit etc/makepkg.*.conf and set PACKAGER first!
69
+ % echo 'PACKAGER="John Doe <john@doe.com>"' >> etc/makepkg.i686.conf
70
+ % echo 'PACKAGER="John Doe <john@doe.com>"' >> etc/makepkg.x86_64.conf
71
+ ```
72
+
73
+ ### Build a package
74
+ Write a PKGBUILD in `PKGBUILDs/#{pkgname}` directory.
75
+
76
+ ```
77
+ % mkdir PKGBUILDs/bar
78
+ % vim PKGBUILDs/bar/PKGBUILD
79
+ ```
80
+
81
+ Then build the package.
82
+
83
+ ```
84
+ % akabei omakase build bar
85
+ (snip)
86
+ % tree foo
87
+ foo
88
+ `-- os
89
+ |-- i686
90
+ | |-- bar-1.0.0-1-i686.pkg.tar.xz
91
+ | |-- bar-1.0.0-1-i686.pkg.tar.xz.sig
92
+ | |-- foo.abs.tar.gz
93
+ | |-- foo.db
94
+ | |-- foo.db.sig
95
+ | `-- foo.files
96
+ `-- x86_64
97
+ |-- bar-1.0.0-1-x86_64.pkg.tar.xz
98
+ |-- bar-1.0.0-1-x86_64.pkg.tar.xz.sig
99
+ |-- foo.abs.tar.gz
100
+ |-- foo.db
101
+ |-- foo.db.sig
102
+ `-- foo.files
103
+ ```
104
+
105
+ ### Publish the repository
106
+ For the server, serve files under the foo directory by HTTP server like nginx or Apache.
107
+
108
+ For clients, add the server's repository configuration to /etc/pacman.conf like below.
109
+
110
+ ```
111
+ [foo]
112
+ SigLevel = Required
113
+ Server = http://example.com/$repo/os/$arch
114
+ ```
115
+
116
+ ### Publish the repository (Amazon S3)
117
+ Initialize repository with `--s3` option and set your credentials to .akabei.yml.
118
+ aws-sdk gem is required.
119
+
120
+ Each time you execute `akabei omakase build`:
121
+
122
+ 1. Download repository databases (not including packages)
123
+ 2. Build a package
124
+ 3. Upload the built package and repository databases.
125
+
49
126
  ## Contributing
50
127
 
51
128
  1. Fork it ( https://github.com/eagletmt/akabei/fork )
data/Rakefile CHANGED
@@ -12,3 +12,31 @@ namespace :spec do
12
12
  desc 'Run RSpec examples including :arch. It requires sudo and devtools package.'
13
13
  task :arch => %w[spec:set_arch spec]
14
14
  end
15
+
16
+ namespace :template do
17
+ desc 'Update makepkg.conf and pacman.conf'
18
+ task :update do
19
+ h = `LANG=C pacman -Qi pacman`.each_line.map(&:chomp).each_with_object({}) do |line, h|
20
+ next if line.empty?
21
+ m = line.match(/\A([^:]+?)\s*:\s*(.+)\z/)
22
+ h[m[1]] = m[2]
23
+ end
24
+ current_pacman = h['Version']
25
+
26
+ require 'akabei/archive_utils'
27
+ cache_dir = '/var/cache/pacman/pkg'
28
+ template_dir = Pathname.new(__FILE__).join('../lib/akabei/omakase/templates')
29
+ %w[i686 x86_64].each do |arch|
30
+ Akabei::ArchiveUtils.each_entry("#{cache_dir}/pacman-#{current_pacman}-#{arch}.pkg.tar.xz") do |entry, archive|
31
+ case entry.pathname
32
+ when 'etc/makepkg.conf'
33
+ puts "Update makepkg.#{arch}.conf"
34
+ template_dir.join("makepkg.#{arch}.conf").open('w') { |f| f.write(archive.read_data) }
35
+ when 'etc/pacman.conf'
36
+ puts "Update pacman.#{arch}.conf"
37
+ template_dir.join("pacman.#{arch}.conf").open('w') { |f| f.write(archive.read_data) }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -20,7 +20,9 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.add_dependency "gpgme"
22
22
  spec.add_dependency "libarchive"
23
+ spec.add_dependency "safe_yaml"
23
24
  spec.add_dependency "thor"
25
+ spec.add_development_dependency "aws-sdk"
24
26
  spec.add_development_dependency "bundler"
25
27
  spec.add_development_dependency "coveralls"
26
28
  spec.add_development_dependency "rake"
@@ -0,0 +1,15 @@
1
+ module Akabei
2
+ module BuildHelper
3
+ def build_in_chroot(builder, chroot, repo_db, repo_files, abs, package_dir)
4
+ chroot.with_chroot do
5
+ packages = builder.build_package(package_dir, chroot)
6
+ packages.each do |package|
7
+ repo_db.add(package)
8
+ repo_files.add(package)
9
+ end
10
+ abs.add(package_dir, builder)
11
+ packages
12
+ end
13
+ end
14
+ end
15
+ end
@@ -10,6 +10,13 @@ module Akabei
10
10
  attr_path_accessor :srcdest, :pkgdest, :logdest
11
11
  attr_accessor :signer
12
12
 
13
+ def initialize(opts = {})
14
+ self.srcdest = opts[:srcdest]
15
+ self.pkgdest = opts[:pkgdest]
16
+ self.logdest = opts[:logdest]
17
+ self.signer = opts[:signer]
18
+ end
19
+
13
20
  def build_package(dir, chroot_tree)
14
21
  Dir.mktmpdir do |tmp_pkgdest|
15
22
  wrap_dir(:srcdest) do
@@ -13,6 +13,7 @@ module Akabei
13
13
  end
14
14
  end
15
15
 
16
+ attr_reader :root, :arch
16
17
  extend AttrPath
17
18
  attr_path_accessor :makepkg_config, :pacman_config
18
19
 
@@ -1,6 +1,8 @@
1
1
  require 'akabei/abs'
2
+ require 'akabei/build_helper'
2
3
  require 'akabei/builder'
3
4
  require 'akabei/chroot_tree'
5
+ require 'akabei/omakase/cli'
4
6
  require 'akabei/package'
5
7
  require 'akabei/repository'
6
8
  require 'akabei/signer'
@@ -41,6 +43,7 @@ module Akabei
41
43
  end
42
44
  extend CommonOptions
43
45
 
46
+ include BuildHelper
44
47
  desc 'build DIR', 'Build package in chroot environment'
45
48
  option :chroot_dir,
46
49
  desc: 'Path to chroot top',
@@ -75,44 +78,28 @@ module Akabei
75
78
  common_options :repo_name, :repo_key, :srcdest
76
79
  def build(package_dir)
77
80
  chroot = ChrootTree.new(options[:chroot_dir], options[:arch])
78
- if options[:makepkg_config]
79
- chroot.makepkg_config = options[:makepkg_config]
80
- end
81
- if options[:pacman_config]
82
- chroot.pacman_config = options[:pacman_config]
83
- end
84
-
85
- repo_db = Repository.new
86
- repo_db.signer = options[:repo_key] && Signer.new(options[:repo_key])
87
- repo_files = Repository.new
88
- repo_files.include_files = true
89
-
90
- builder = Builder.new
91
- builder.signer = options[:package_key] && Signer.new(options[:package_key])
92
- builder.srcdest = options[:srcdest]
93
- builder.logdest = options[:logdest]
81
+ chroot.makepkg_config = options[:makepkg_config]
82
+ chroot.pacman_config = options[:pacman_config]
94
83
 
95
84
  repo_path = Pathname.new(options[:repo_dir])
96
85
  repo_name = options[:repo_name]
97
- builder.pkgdest = repo_path
86
+ builder = Builder.new(
87
+ signer: Signer.get(options[:package_key]),
88
+ srcdest: options[:srcdest],
89
+ logdest: options[:logdest],
90
+ pkgdest: repo_path,
91
+ )
98
92
 
99
93
  db_path = repo_path.join("#{repo_name}.db")
100
94
  files_path = repo_path.join("#{repo_name}.files")
101
- repo_db.load(db_path)
102
- repo_files.load(files_path)
95
+ repo_db = Repository.load(db_path, signer: Signer.get(options[:repo_key]))
96
+ repo_files = Repository.load(files_path, include_files: true)
103
97
 
104
98
  abs = Abs.new(repo_path.join("#{repo_name}.abs.tar.gz"), repo_name)
105
99
 
106
- chroot.with_chroot do
107
- packages = builder.build_package(package_dir, chroot)
108
- packages.each do |package|
109
- repo_db.add(package)
110
- repo_files.add(package)
111
- end
112
- abs.add(package_dir, builder)
113
- repo_db.save(db_path)
114
- repo_files.save(files_path)
115
- end
100
+ build_in_chroot(builder, chroot, repo_db, repo_files, abs, package_dir)
101
+ repo_db.save(db_path)
102
+ repo_files.save(files_path)
116
103
  end
117
104
 
118
105
  desc 'abs-add DIR ABS_TARBALL', 'Add the package inside DIR to ABS_TARBALL'
@@ -168,5 +155,7 @@ module Akabei
168
155
  repo.remove(package_name)
169
156
  repo.save(db_path)
170
157
  end
158
+
159
+ Akabei::CLI.register(Akabei::Omakase::CLI, 'omakase', 'omakase <command>', 'Omakase mode')
171
160
  end
172
161
  end
@@ -0,0 +1,116 @@
1
+ require 'akabei/build_helper'
2
+ require 'akabei/omakase/config'
3
+ require 'akabei/omakase/s3'
4
+ require 'thor'
5
+
6
+ module Akabei
7
+ module Omakase
8
+ class CLI < Thor
9
+ namespace :omakase
10
+
11
+ include Thor::Actions
12
+ include Thor::Shell
13
+ include BuildHelper
14
+
15
+ def self.source_root
16
+ File.expand_path('../templates', __FILE__)
17
+ end
18
+
19
+ def self.banner(task, namespace = nil, subcommand = false)
20
+ super(task, nil, true)
21
+ end
22
+
23
+ desc 'init NAME', "Generate omakase template for NAME repository"
24
+ option :repo_key,
25
+ desc: 'GPG key to sign repository database',
26
+ banner: 'GPGKEY',
27
+ type: :string
28
+ option :package_key,
29
+ desc: 'GPG key to sign repository database',
30
+ banner: 'GPGKEY',
31
+ type: :string
32
+ option :s3,
33
+ desc: 'Enable S3 repository',
34
+ type: :boolean,
35
+ default: false
36
+ def init(name)
37
+ # Check key's validity
38
+ if options[:repo_key]
39
+ Signer.new(options[:repo_key])
40
+ end
41
+ if options[:package_key]
42
+ Signer.new(options[:package_key])
43
+ end
44
+
45
+ if options[:s3]
46
+ begin
47
+ require 'aws-sdk'
48
+ rescue LoadError => e
49
+ say("WARNING: You don't have aws-sdk installed. Disable S3 repository.", :yellow)
50
+ options[:s3] = false
51
+ end
52
+ end
53
+
54
+ @name = name
55
+ @archs = %w[i686 x86_64]
56
+ template('.akabei.yml.tt')
57
+ empty_directory(name)
58
+ empty_directory('sources')
59
+ empty_directory('logs')
60
+ empty_directory('PKGBUILDs')
61
+ empty_directory('etc')
62
+ @archs.each do |arch|
63
+ copy_file("makepkg.#{arch}.conf", "etc/makepkg.#{arch}.conf")
64
+ copy_file("pacman.#{arch}.conf", "etc/pacman.#{arch}.conf")
65
+ end
66
+
67
+ say('Edit etc/makepkg.*.conf and set PACKAGER first!', :green)
68
+ end
69
+
70
+ desc 'build PACKAGE_NAME', "build PACKAGE_NAME"
71
+ def build(package_name)
72
+ builder = Builder.new(
73
+ signer: config.package_signer,
74
+ srcdest: config.srcdest,
75
+ logdest: config.logdest,
76
+ )
77
+ repo_signer = config.repo_signer
78
+
79
+ s3 = S3.new(config['s3'], shell)
80
+
81
+ config.builds.each do |arch, config_file|
82
+ chroot = ChrootTree.new(nil, arch)
83
+ chroot.makepkg_config = config_file['makepkg']
84
+ chroot.pacman_config = config_file['pacman']
85
+
86
+ repo_path = config.repo_path(arch)
87
+ repo_path.mkpath
88
+ builder.pkgdest = repo_path
89
+
90
+ db_path = config.db_path(arch)
91
+ files_path = config.files_path(arch)
92
+ abs = Abs.new(config.abs_path(arch), config.name)
93
+
94
+ s3.before!(config, arch)
95
+ repo_db = Repository.load(db_path, signer: repo_signer)
96
+ repo_files = Repository.load(files_path, include_files: true)
97
+
98
+ packages = build_in_chroot(builder, chroot, repo_db, repo_files, abs, config.package_dir(package_name))
99
+ repo_db.save(db_path)
100
+ repo_files.save(files_path)
101
+ s3.after!(config, arch, packages)
102
+ end
103
+ end
104
+
105
+ private
106
+
107
+ def config
108
+ @config ||= begin
109
+ c = Config.load
110
+ c.validate!
111
+ c
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,113 @@
1
+ require 'akabei/error'
2
+ require 'akabei/signer'
3
+ require 'forwardable'
4
+ require 'safe_yaml/load'
5
+
6
+ module Akabei
7
+ module Omakase
8
+ class Config
9
+ class InvalidConfig < Error
10
+ end
11
+
12
+ FILE_NAME = '.akabei.yml'
13
+
14
+ def self.load
15
+ config = new
16
+ config.load(FILE_NAME)
17
+ config
18
+ end
19
+
20
+ extend Forwardable
21
+ def_delegators :@config, :[], :each
22
+ include Enumerable
23
+
24
+ def initialize
25
+ @config = {}
26
+ end
27
+
28
+ def load(path)
29
+ @config.merge!(SafeYAML.load_file(path, deserialize_symbols: true))
30
+ true
31
+ rescue Errno::ENOENT
32
+ false
33
+ end
34
+
35
+ REQUIRED_ATTRIBUTES = %w[
36
+ name
37
+ package_key
38
+ repo_key
39
+ srcdest
40
+ logdest
41
+ pkgbuild
42
+ ].freeze
43
+ REQUIRED_BUILD_ATTRIBUTES = %w[makepkg pacman]
44
+
45
+ def validate!
46
+ REQUIRED_ATTRIBUTES.each do |attr|
47
+ unless @config.has_key?(attr)
48
+ raise InvalidConfig.new("#{attr.inspect} is required")
49
+ end
50
+ end
51
+ unless @config['builds'].is_a?(Hash)
52
+ raise InvalidConfig.new('"builds" must be a Hash')
53
+ end
54
+ @config['builds'].each do |arch, config_file|
55
+ REQUIRED_BUILD_ATTRIBUTES.each do |attr|
56
+ unless config_file.has_key?(attr)
57
+ raise InvalidConfig.new("builds.#{arch}: #{attr.inspect} is required")
58
+ end
59
+ end
60
+ end
61
+ true
62
+ end
63
+
64
+ def name
65
+ @config['name']
66
+ end
67
+
68
+ def srcdest
69
+ Pathname.new(@config['srcdest'])
70
+ end
71
+
72
+ def logdest
73
+ Pathname.new(@config['logdest'])
74
+ end
75
+
76
+ def pkgbuild
77
+ Pathname.new(@config['pkgbuild'])
78
+ end
79
+
80
+ def package_dir(package_name)
81
+ pkgbuild.join(package_name)
82
+ end
83
+
84
+ def package_signer
85
+ Signer.get(@config['package_key'])
86
+ end
87
+
88
+ def repo_signer
89
+ Signer.get(@config['repo_key'])
90
+ end
91
+
92
+ def builds
93
+ @config['builds']
94
+ end
95
+
96
+ def repo_path(arch)
97
+ Pathname.new(@config['name']).join('os', arch)
98
+ end
99
+
100
+ def db_path(arch)
101
+ repo_path(arch).join("#{@config['name']}.db")
102
+ end
103
+
104
+ def files_path(arch)
105
+ repo_path(arch).join("#{@config['name']}.files")
106
+ end
107
+
108
+ def abs_path(arch)
109
+ repo_path(arch).join("#{@config['name']}.abs.tar.gz")
110
+ end
111
+ end
112
+ end
113
+ end