Commit | Line | Data |
afd7c030 |
1 | package System::Introspector::Probe::Packages::Apt; |
97b10529 |
2 | use Moo; |
5413434d |
3 | use File::Basename; |
97b10529 |
4 | |
9ee104cc |
5 | use System::Introspector::Util qw( |
6 | handle_from_command |
7 | transform_exceptions |
5413434d |
8 | output_from_file |
9 | files_from_dir |
9ee104cc |
10 | ); |
11 | |
025e0d3f |
12 | has apt_lists_dir => (is => 'ro', builder => 1); |
13 | has apt_update_after => (is => 'ro', default => sub { 86400 }); |
14 | has apt_update => (is => 'ro'); |
15 | |
5413434d |
16 | has apt_sources => (is => 'ro', builder => 1); |
17 | has apt_sources_dir => (is => 'ro', builder => 1); |
18 | |
19 | sub _build_apt_lists_dir { '/var/lib/apt/lists' } |
20 | sub _build_apt_sources { '/etc/apt/sources.list' } |
21 | sub _build_apt_sources_dir { '/etc/apt/sources.list.d' } |
025e0d3f |
22 | |
97b10529 |
23 | sub gather { |
24 | my ($self) = @_; |
25 | return { |
025e0d3f |
26 | update => { |
27 | last => $self->_last_apt_update, |
28 | run => transform_exceptions { |
29 | return { result => $self->_check_apt_state }; |
30 | }, |
31 | }, |
9ee104cc |
32 | installed => transform_exceptions { |
33 | return { packages => $self->_gather_installed }; |
34 | }, |
025e0d3f |
35 | upgradable => transform_exceptions { |
36 | return { actions => $self->_gather_upgradable }; |
37 | }, |
5413434d |
38 | sources => transform_exceptions { |
39 | return { config => $self->_gather_sources }; |
40 | }, |
97b10529 |
41 | }; |
42 | } |
43 | |
025e0d3f |
44 | sub _last_apt_update { |
45 | my ($self) = @_; |
46 | return scalar( (stat($self->apt_lists_dir))[9] ); |
47 | } |
48 | |
49 | sub _check_apt_state { |
50 | my ($self) = @_; |
51 | return 'disabled' unless $self->apt_update; |
52 | my $threshold = $self->apt_update_after; |
53 | my $last_change = $self->_last_apt_update; |
54 | return 'no'if ($last_change + $threshold) > time; |
55 | handle_from_command 'apt-get update'; |
56 | return 'yes'; |
57 | } |
58 | |
3d4ae7f9 |
59 | sub _open_dpkg_query_pipe { |
97b10529 |
60 | my ($self) = @_; |
9ee104cc |
61 | return handle_from_command 'dpkg-query --show'; |
3d4ae7f9 |
62 | } |
63 | |
025e0d3f |
64 | sub _open_apt_get_upgrade_simulation_pipe { |
65 | my ($self) = @_; |
66 | return handle_from_command 'apt-get -s upgrade'; |
67 | } |
68 | |
5413434d |
69 | sub _gather_sources { |
70 | my ($self) = @_; |
71 | my $sources_dir = $self->apt_sources_dir; |
72 | return { |
73 | 'sources_list' => $self->_fetch_source_list($self->apt_sources), |
74 | 'sources_list_dir' => (-e $sources_dir) ? transform_exceptions { |
75 | return +{ files => +{ map { |
76 | ($_, $self->_fetch_source_list("$sources_dir/$_")); |
77 | } files_from_dir $sources_dir } }; |
78 | } : {}, |
79 | }; |
80 | } |
81 | |
82 | sub _fetch_source_list { |
83 | my ($self, $file) = @_; |
84 | return transform_exceptions { |
85 | return { |
86 | file => { |
87 | file_name => $file, |
88 | body => scalar(output_from_file $file), |
89 | }, |
90 | }; |
91 | }; |
92 | } |
93 | |
025e0d3f |
94 | sub _gather_upgradable { |
95 | my ($self) = @_; |
96 | my $pipe = $self->_open_apt_get_upgrade_simulation_pipe; |
97 | my %action; |
98 | while (defined( my $line = <$pipe> )) { |
99 | chomp $line; |
100 | if ($line =~ m{^(inst|remv)\s+(\S+)\s+(.+)$}i) { |
101 | $action{ lc($1) }{ $2 } = $3; |
102 | } |
103 | } |
104 | return \%action; |
105 | } |
106 | |
3d4ae7f9 |
107 | sub _gather_installed { |
108 | my ($self) = @_; |
109 | my $pipe = $self->_open_dpkg_query_pipe; |
97b10529 |
110 | my %package; |
111 | while (defined( my $line = <$pipe> )) { |
112 | chomp $line; |
113 | my ($package, $version) = split m{\s+}, $line; |
114 | $package{ $package } = { |
115 | version => $version, |
116 | }; |
117 | } |
118 | return \%package; |
119 | } |
120 | |
121 | 1; |
535e84b6 |
122 | |
123 | __END__ |
124 | |
125 | =head1 NAME |
126 | |
127 | System::Introspector::Packages::Apt - Gather APT package status |
128 | |
129 | =head1 DESCRIPTION |
130 | |
131 | Uses C<dpkg-query> to list all installed packages. |
132 | |
133 | =head1 SEE ALSO |
134 | |
135 | =over |
136 | |
137 | =item L<System::Introspector> |
138 | |
139 | =back |
140 | |
141 | =cut |