akabei 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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