vx-aptly 0.9.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 +7 -0
- data/.gitignore +23 -0
- data/Dockerfile +11 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +36 -0
- data/bin/vx-aptly +4 -0
- data/doc/aptly.example +16 -0
- data/doc/aptly.upstart +27 -0
- data/doc/cloud-files.example +9 -0
- data/docker/install.sh +47 -0
- data/docker/my_init +57 -0
- data/docker/supervisord.conf +17 -0
- data/lib/vx/aptly.rb +33 -0
- data/lib/vx/aptly/app.rb +194 -0
- data/lib/vx/aptly/cli.sh +116 -0
- data/lib/vx/aptly/config.ru +3 -0
- data/lib/vx/aptly/mixin/capture.rb +37 -0
- data/lib/vx/aptly/package.rb +110 -0
- data/lib/vx/aptly/public/404.html +153 -0
- data/lib/vx/aptly/public/css/animate.css +3158 -0
- data/lib/vx/aptly/public/css/bootstrap.min.css +5 -0
- data/lib/vx/aptly/public/css/flat-ui.css +6007 -0
- data/lib/vx/aptly/public/css/theme.css +131 -0
- data/lib/vx/aptly/public/fonts/glyphicons/flat-ui-icons-regular.eot +0 -0
- data/lib/vx/aptly/public/fonts/glyphicons/flat-ui-icons-regular.svg +126 -0
- data/lib/vx/aptly/public/fonts/glyphicons/flat-ui-icons-regular.ttf +0 -0
- data/lib/vx/aptly/public/fonts/glyphicons/flat-ui-icons-regular.woff +0 -0
- data/lib/vx/aptly/public/fonts/glyphicons/selection.json +2106 -0
- data/lib/vx/aptly/public/fonts/lato/lato-black.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-black.svg +4691 -0
- data/lib/vx/aptly/public/fonts/lato/lato-black.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-black.woff +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bold.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bold.svg +5085 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bold.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bold.woff +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bolditalic.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bolditalic.svg +4514 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bolditalic.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-bolditalic.woff +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-italic.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-italic.svg +4514 -0
- data/lib/vx/aptly/public/fonts/lato/lato-italic.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-italic.woff +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-light.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-light.svg +4691 -0
- data/lib/vx/aptly/public/fonts/lato/lato-light.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-light.woff +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-regular.eot +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-regular.svg +4691 -0
- data/lib/vx/aptly/public/fonts/lato/lato-regular.ttf +0 -0
- data/lib/vx/aptly/public/fonts/lato/lato-regular.woff +0 -0
- data/lib/vx/aptly/public/img/favicon.ico +0 -0
- data/lib/vx/aptly/public/js/app.js +12 -0
- data/lib/vx/aptly/public/js/jquery_ujs.js +446 -0
- data/lib/vx/aptly/repo.rb +161 -0
- data/lib/vx/aptly/repo_publish.rb +165 -0
- data/lib/vx/aptly/version.rb +5 -0
- data/lib/vx/aptly/views/index.erb +94 -0
- data/lib/vx/aptly/views/layout.erb +54 -0
- data/lib/vx/aptly/views/repo_publishes/new.erb +49 -0
- data/lib/vx/aptly/views/repos/edit.erb +17 -0
- data/lib/vx/aptly/views/repos/errors.erb +5 -0
- data/lib/vx/aptly/views/repos/form.erb +26 -0
- data/lib/vx/aptly/views/repos/new.erb +17 -0
- data/lib/vx/aptly/views/repos/packages.erb +51 -0
- data/lib/vx/aptly/views/repos/show.erb +66 -0
- data/spec/lib/repo_publish_spec.rb +60 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/aptly.conf +0 -0
- data/spec/support/home.rb +39 -0
- data/vx-aptly.gemspec +32 -0
- metadata +263 -0
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
module Vx
|
|
2
|
+
module Aptly
|
|
3
|
+
class Repo
|
|
4
|
+
|
|
5
|
+
include Mixin::Capture
|
|
6
|
+
extend Mixin::Capture
|
|
7
|
+
|
|
8
|
+
attr_accessor :error, :attributes, :notice
|
|
9
|
+
|
|
10
|
+
def initialize(params = {})
|
|
11
|
+
@attributes = {}
|
|
12
|
+
params.each do |k,v|
|
|
13
|
+
if self.respond_to?(:"#{k}=")
|
|
14
|
+
self.public_send(:"#{k}=", v)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def persisted!
|
|
20
|
+
@persisted = true
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def new_record?
|
|
24
|
+
!@persisted
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def valid?
|
|
28
|
+
!@error
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def packages(reload = false)
|
|
32
|
+
@packages = nil if reload
|
|
33
|
+
@packages ||= Package.all(self)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
%w{ name comment default_component default_distribution number_of_packages}.each do |m|
|
|
37
|
+
define_method :"#{m}=" do |value|
|
|
38
|
+
if value.is_a?(String) && value == ""
|
|
39
|
+
@attributes[m.to_sym] = nil
|
|
40
|
+
else
|
|
41
|
+
@attributes[m.to_sym] = value
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
define_method :"#{m}" do
|
|
46
|
+
value = @attributes[m.to_sym]
|
|
47
|
+
if value == nil
|
|
48
|
+
case m
|
|
49
|
+
when 'default_distribution'
|
|
50
|
+
value = 'ubuntu'
|
|
51
|
+
when 'default_component'
|
|
52
|
+
value = 'main'
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
value
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create
|
|
60
|
+
line = "aptly repo create"
|
|
61
|
+
line << " -comment=\"#{comment}\"" if comment
|
|
62
|
+
line << " -component=\"#{default_component}\"" if default_component
|
|
63
|
+
line << " -distribution=\"#{default_distribution}\"" if default_distribution
|
|
64
|
+
line << " #{name}" if name
|
|
65
|
+
|
|
66
|
+
begin
|
|
67
|
+
capture line do |re|
|
|
68
|
+
@notice = "The command '#{line}' was successfuly finished with output:\n"
|
|
69
|
+
@notice << re
|
|
70
|
+
end
|
|
71
|
+
persisted!
|
|
72
|
+
rescue AptlyCommandError => e
|
|
73
|
+
@error = e
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
valid?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def update
|
|
80
|
+
line = "aptly repo edit"
|
|
81
|
+
line << " -comment=\"#{comment}\"" if comment
|
|
82
|
+
line << " -component=\"#{default_component}\"" if default_component
|
|
83
|
+
line << " -distribution=\"#{default_distribution}\"" if default_distribution
|
|
84
|
+
line << " #{name}" if name
|
|
85
|
+
|
|
86
|
+
begin
|
|
87
|
+
capture line do |re|
|
|
88
|
+
@notice = "The command '#{line}' was successfuly finished with output:\n"
|
|
89
|
+
@notice << re
|
|
90
|
+
end
|
|
91
|
+
rescue AptlyCommandError => e
|
|
92
|
+
@error = e
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
valid?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def destroy
|
|
99
|
+
cmd = "aptly repo drop"
|
|
100
|
+
cmd << " #{name}" if name
|
|
101
|
+
capture cmd do |re|
|
|
102
|
+
@notice = "The command '#{cmd}' was successfuly finished with output:\n"
|
|
103
|
+
@notice << re
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def publishes(reload = false)
|
|
108
|
+
@publishes = nil if reload
|
|
109
|
+
@publishes ||= RepoPublish.for_repo(self)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def build_publish(options = {})
|
|
113
|
+
options[:repo_name] = self.name
|
|
114
|
+
options = {
|
|
115
|
+
component: default_component,
|
|
116
|
+
distribution: default_distribution
|
|
117
|
+
}.merge(options)
|
|
118
|
+
|
|
119
|
+
RepoPublish.new(options)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
class << self
|
|
123
|
+
|
|
124
|
+
def find(name)
|
|
125
|
+
capture "aptly repo show #{name}" do |re|
|
|
126
|
+
repo = new(name: name)
|
|
127
|
+
repo.persisted!
|
|
128
|
+
|
|
129
|
+
re.lines.each do |line|
|
|
130
|
+
key, value = line.split(":").map(&:strip)
|
|
131
|
+
case key
|
|
132
|
+
when 'Comment'
|
|
133
|
+
repo.comment = value
|
|
134
|
+
when 'Default Distribution'
|
|
135
|
+
repo.default_distribution = value
|
|
136
|
+
when 'Default Component'
|
|
137
|
+
repo.default_component = value
|
|
138
|
+
when 'Number of packages'
|
|
139
|
+
repo.number_of_packages = value.to_i
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
repo
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def all
|
|
148
|
+
capture "aptly repo list" do |re|
|
|
149
|
+
re.lines.inject([]) do |a, line|
|
|
150
|
+
if line =~ / \* \[(.*)\]/
|
|
151
|
+
a << find($1)
|
|
152
|
+
end
|
|
153
|
+
a
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
module Vx
|
|
2
|
+
module Aptly
|
|
3
|
+
class RepoPublish
|
|
4
|
+
|
|
5
|
+
PublishedRepo = Struct.new(:name, :component)
|
|
6
|
+
|
|
7
|
+
include Mixin::Capture
|
|
8
|
+
extend Mixin::Capture
|
|
9
|
+
|
|
10
|
+
attr_reader :attributes, :error, :notice
|
|
11
|
+
|
|
12
|
+
def initialize(params = {})
|
|
13
|
+
@attributes = {}
|
|
14
|
+
params.each do |k,v|
|
|
15
|
+
if self.respond_to?(:"#{k}=")
|
|
16
|
+
self.public_send(:"#{k}=", v)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def id
|
|
22
|
+
[prefix, distribution].join("/")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def valid?
|
|
26
|
+
!@error
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def create
|
|
30
|
+
line = "aptly publish repo"
|
|
31
|
+
line << " -architectures=\"#{architectures}\"" if architectures
|
|
32
|
+
|
|
33
|
+
components = repos.map{|i| "" }.join(",") # all components
|
|
34
|
+
line << " -component=\"#{components}\""
|
|
35
|
+
|
|
36
|
+
line << " -distribution=\"#{distribution}\"" if distribution
|
|
37
|
+
|
|
38
|
+
repos.each do |repo|
|
|
39
|
+
line << " #{repo.name}"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
if repos.any? && prefix
|
|
43
|
+
line << " #{prefix}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
begin
|
|
47
|
+
capture line do |re|
|
|
48
|
+
@notice = "The command '#{line}' was successfuly finished with output:\n"
|
|
49
|
+
@notice << re
|
|
50
|
+
end
|
|
51
|
+
rescue AptlyCommandError => e
|
|
52
|
+
@error = e
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
valid?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def update
|
|
59
|
+
begin
|
|
60
|
+
line = update_command_line
|
|
61
|
+
capture line do |re|
|
|
62
|
+
@notice = "The command '#{line}' was successfuly finished with output:\n"
|
|
63
|
+
@notice << re
|
|
64
|
+
end
|
|
65
|
+
rescue AptlyCommandError => e
|
|
66
|
+
@error = e
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
valid?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def update_command_line
|
|
73
|
+
line = "aptly publish update"
|
|
74
|
+
line << " -architectures=\"#{architectures}\"" if architectures
|
|
75
|
+
line << " #{distribution}" if distribution
|
|
76
|
+
line << " #{prefix}" if distribution && prefix
|
|
77
|
+
line
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def destroy
|
|
81
|
+
line = "aptly publish drop "
|
|
82
|
+
line << " -architectures=\"#{architectures}\"" if architectures
|
|
83
|
+
line << " #{distribution}" if distribution
|
|
84
|
+
line << " #{prefix}" if distribution && prefix
|
|
85
|
+
begin
|
|
86
|
+
capture line do |re|
|
|
87
|
+
@notice = "The command '#{line}' was successfuly finished with output:\n"
|
|
88
|
+
@notice << re
|
|
89
|
+
end
|
|
90
|
+
rescue AptlyCommandError => e
|
|
91
|
+
@error = e
|
|
92
|
+
end
|
|
93
|
+
valid?
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
%w{ prefix component architectures distribution }.each do |m|
|
|
97
|
+
define_method :"#{m}=" do |value|
|
|
98
|
+
if value.to_s.strip == ''
|
|
99
|
+
value = nil
|
|
100
|
+
end
|
|
101
|
+
@attributes[m.to_sym] = value
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
define_method :"#{m}" do
|
|
105
|
+
@attributes[m.to_sym]
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def repos=(val)
|
|
110
|
+
@attributes[:repos] = []
|
|
111
|
+
if val.is_a?(Array)
|
|
112
|
+
val.each do |repo|
|
|
113
|
+
if repo.is_a?(Hash)
|
|
114
|
+
@attributes[:repos].push PublishedRepo.new(repo[:name], repo[:component])
|
|
115
|
+
else
|
|
116
|
+
@attributes[:repos].push PublishedRepo.new(repo.to_s)
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
@attributes[:repos]
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def repos
|
|
124
|
+
@attributes[:repos] ||= []
|
|
125
|
+
@attributes[:repos]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
class << self
|
|
129
|
+
def all(options = {})
|
|
130
|
+
capture 'aptly publish list' do |re|
|
|
131
|
+
re.lines.inject([]) do |a,line|
|
|
132
|
+
if line =~ /\* (.+)\/(.+) \[(.+)\] publishes (.*)$/
|
|
133
|
+
it = new(prefix: $1, distribution: $2, architectures: $3)
|
|
134
|
+
repos = $4
|
|
135
|
+
published_repos = []
|
|
136
|
+
|
|
137
|
+
repos.split(",").map(&:strip).map do |repo|
|
|
138
|
+
if repo =~ /\{(.*): \[(.*)\]/
|
|
139
|
+
published_repos << { name: $2, component: $1 }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it.repos = published_repos
|
|
144
|
+
|
|
145
|
+
a << it
|
|
146
|
+
end
|
|
147
|
+
a
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def for_repo(repo)
|
|
153
|
+
all.select{|pub| pub.repos.map(&:name).include?(repo.name) }
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
def find(id)
|
|
157
|
+
if id.split("/").size == 1
|
|
158
|
+
id = "./#{id}"
|
|
159
|
+
end
|
|
160
|
+
all.find{|pub| pub.id == id } or raise(PublishNotFoundError, "The publish with id #{id} was not found")
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<% @menu = [['Dashboard', '/', true]] %>
|
|
2
|
+
|
|
3
|
+
<% if @repos.any? %>
|
|
4
|
+
<div class="panel panel-default">
|
|
5
|
+
<div class="panel-heading">
|
|
6
|
+
<div class="pull-right">
|
|
7
|
+
<a href="/repos/new" class="btn btn-default btn-sm">
|
|
8
|
+
<%= ico 'plus' %>
|
|
9
|
+
Add a repo
|
|
10
|
+
</a>
|
|
11
|
+
</div>
|
|
12
|
+
<h6>Repos</h6>
|
|
13
|
+
</div>
|
|
14
|
+
<table class="table table-hover">
|
|
15
|
+
<% for repo in @repos %>
|
|
16
|
+
<tr>
|
|
17
|
+
<td>
|
|
18
|
+
<a href="/repos/<%= repo.name %>">
|
|
19
|
+
<small>
|
|
20
|
+
<%= repo.name %> (<%= repo.number_of_packages %>)
|
|
21
|
+
</small>
|
|
22
|
+
</a>
|
|
23
|
+
</td>
|
|
24
|
+
<td><small class="text-muted"><%= repo.comment %></small></td>
|
|
25
|
+
<td><small class=""><%= repo.default_distribution %></small></td>
|
|
26
|
+
<td><small class=""><%= repo.default_component %></small></td>
|
|
27
|
+
</tr>
|
|
28
|
+
<% end %>
|
|
29
|
+
</table>
|
|
30
|
+
</div>
|
|
31
|
+
<% else %>
|
|
32
|
+
<div class="jumbotron">
|
|
33
|
+
<p class="lead">You have no repositories</p>
|
|
34
|
+
<p><a class="btn btn-lg btn-success" href="/repos/new" role="button">
|
|
35
|
+
<%= ico 'plus' %>
|
|
36
|
+
Create one
|
|
37
|
+
</a></p>
|
|
38
|
+
</div>
|
|
39
|
+
<% end %>
|
|
40
|
+
|
|
41
|
+
<% if @pubs.any? %>
|
|
42
|
+
<div class="panel panel-default">
|
|
43
|
+
<div class="panel-heading">
|
|
44
|
+
<div class="pull-right">
|
|
45
|
+
<a href="/repo/publishes/new" class="btn btn-default btn-sm">
|
|
46
|
+
<%= ico 'plus' %>
|
|
47
|
+
Add a publish
|
|
48
|
+
</a>
|
|
49
|
+
</div>
|
|
50
|
+
<h6>Published Repos</h6>
|
|
51
|
+
</div>
|
|
52
|
+
<table class="table table-hover table-btn-group">
|
|
53
|
+
<% for pub in @pubs %>
|
|
54
|
+
<tr>
|
|
55
|
+
<td>
|
|
56
|
+
<small><%= pub.id %></small>
|
|
57
|
+
</td>
|
|
58
|
+
<td>
|
|
59
|
+
<small><%= pub.architectures %></small>
|
|
60
|
+
</td>
|
|
61
|
+
<td>
|
|
62
|
+
<% for repo in pub.repos %>
|
|
63
|
+
<a href="/repos/<%= repo.name %>" style="display:block">
|
|
64
|
+
<small class=""><%= repo.name %> (<%= repo.component %>)</small>
|
|
65
|
+
</a>
|
|
66
|
+
<% end %>
|
|
67
|
+
</td>
|
|
68
|
+
<td>
|
|
69
|
+
<div class="btn-group">
|
|
70
|
+
<a class="btn btn-xs btn-primary" href="/repo/publishes/<%= pub.id %>" data-method="patch" data-confirm="Are you sure?">
|
|
71
|
+
<%= ico 'upload' %>
|
|
72
|
+
Update
|
|
73
|
+
</a>
|
|
74
|
+
<a class="btn btn-xs btn-danger" href="/repo/publishes/<%= pub.id %>" data-method="delete" data-confirm="Are you sure?">
|
|
75
|
+
<%= ico 'cross' %>
|
|
76
|
+
Remove
|
|
77
|
+
</a>
|
|
78
|
+
</div>
|
|
79
|
+
</td>
|
|
80
|
+
</tr>
|
|
81
|
+
<% end %>
|
|
82
|
+
</table>
|
|
83
|
+
</div>
|
|
84
|
+
<% else %>
|
|
85
|
+
<% if @repos.any? %>
|
|
86
|
+
<div class="jumbotron">
|
|
87
|
+
<p class="lead">You have no published repos</p>
|
|
88
|
+
<p><a class="btn btn-lg btn-success" href="/repo/publishes/new" role="button">
|
|
89
|
+
<%= ico 'plus' %>
|
|
90
|
+
Create one
|
|
91
|
+
</a></p>
|
|
92
|
+
</div>
|
|
93
|
+
<% end %>
|
|
94
|
+
<% end %>
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
7
|
+
|
|
8
|
+
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
|
9
|
+
<link rel="stylesheet" href="/css/flat-ui.css">
|
|
10
|
+
<link rel="stylesheet" href="/css/animate.css">
|
|
11
|
+
<link rel="stylesheet" href="/css/theme.css">
|
|
12
|
+
|
|
13
|
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
|
|
14
|
+
<script src="/js/jquery_ujs.js"></script>
|
|
15
|
+
<script src="/js/app.js"></script>
|
|
16
|
+
|
|
17
|
+
<link rel="shortcut icon" href="img/favicon.ico">
|
|
18
|
+
|
|
19
|
+
<title>Aptly Web</title>
|
|
20
|
+
</head>
|
|
21
|
+
|
|
22
|
+
<body>
|
|
23
|
+
|
|
24
|
+
<a href="https://github.com/vexor/vx-aptly" target="_blank"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png"></a>
|
|
25
|
+
|
|
26
|
+
<div class="container">
|
|
27
|
+
<div class="header">
|
|
28
|
+
<% if @menu %>
|
|
29
|
+
<ul class="nav nav-pills " role="tablist">
|
|
30
|
+
<% for name, url, active in @menu %>
|
|
31
|
+
<li role="presentation" class="<%= 'active' if active %>"><a href="<%= url %>"><%= name %></a></li>
|
|
32
|
+
<% end %>
|
|
33
|
+
</ul>
|
|
34
|
+
<% end %>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<% if flash[:notice] %>
|
|
38
|
+
<pre class="notice"><%= flash[:notice] %></pre>
|
|
39
|
+
<% end %>
|
|
40
|
+
<% if flash[:error] %>
|
|
41
|
+
<pre class="error"><%= flash[:error] %></pre>
|
|
42
|
+
<% end %>
|
|
43
|
+
|
|
44
|
+
<%= yield %>
|
|
45
|
+
<!--
|
|
46
|
+
<div class="footer">
|
|
47
|
+
<p>© Vexor 2014</p>
|
|
48
|
+
</div>
|
|
49
|
+
-->
|
|
50
|
+
|
|
51
|
+
</div> <!-- /container -->
|
|
52
|
+
</body>
|
|
53
|
+
</html>
|
|
54
|
+
|