machinery-tool 1.17.0 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.git_revision +1 -1
- data/NEWS +17 -1
- data/bin/machinery +1 -1
- data/export_helpers/merge_users_and_groups.pl.erb +1 -1
- data/html/comparison.html.haml +14 -9
- data/html/index.html.haml +5 -2
- data/html/landing_page.html.haml +4 -1
- data/html/partials/changed_managed_files.html.haml +2 -0
- data/html/partials/compare/alert.html.haml +1 -1
- data/html/partials/compare/unmanaged_file_list.html.haml +12 -0
- data/html/partials/config_files.html.haml +2 -0
- data/html/partials/landing_page/alert.html.haml +1 -1
- data/html/partials/unmanaged_files.html.haml +14 -0
- data/inspect_helpers/changed_files.sh +1 -1
- data/inspect_helpers/dpkg_unmanaged_files.sh +1 -1
- data/inspect_helpers/yum_repositories.py +1 -1
- data/lib/analyze_config_file_diffs_task.rb +1 -1
- data/lib/array.rb +1 -1
- data/lib/autoyast.rb +34 -34
- data/lib/build_task.rb +1 -1
- data/lib/cli.rb +21 -6
- data/lib/compare_task.rb +1 -1
- data/lib/comparison.rb +1 -1
- data/lib/config.rb +1 -1
- data/lib/config_base.rb +1 -1
- data/lib/config_task.rb +1 -1
- data/lib/constants.rb +2 -2
- data/lib/containerize_task.rb +1 -1
- data/lib/containerized_app.rb +1 -1
- data/lib/copy_task.rb +1 -1
- data/lib/current_user.rb +1 -1
- data/lib/deploy_task.rb +1 -1
- data/lib/docker_system.rb +4 -5
- data/lib/dpkg_database.rb +2 -2
- data/lib/element_filter.rb +1 -1
- data/lib/exceptions.rb +2 -2
- data/lib/export_task.rb +1 -1
- data/lib/exporter.rb +1 -1
- data/lib/file_diff.rb +1 -1
- data/lib/file_scope.rb +1 -1
- data/lib/file_validator.rb +1 -1
- data/lib/filter.rb +1 -1
- data/lib/filter_option_parser.rb +1 -1
- data/lib/helper.rb +1 -1
- data/lib/hint.rb +1 -1
- data/lib/html.rb +1 -1
- data/lib/inspect_task.rb +1 -1
- data/lib/inspector.rb +1 -1
- data/lib/json_schema_monkey_patch.rb +35 -0
- data/lib/json_validation_error_cleaner.rb +1 -1
- data/lib/json_validator.rb +1 -1
- data/lib/kiwi_config.rb +69 -67
- data/lib/list_task.rb +1 -1
- data/lib/local_system.rb +1 -1
- data/lib/logged_cheetah.rb +1 -1
- data/lib/machinery.rb +6 -2
- data/lib/machinery_helper.rb +28 -8
- data/lib/machinery_logger.rb +1 -1
- data/lib/man_task.rb +50 -5
- data/lib/managed_files_database.rb +24 -17
- data/lib/manifest.rb +3 -2
- data/lib/migration.rb +1 -1
- data/lib/mountpoints.rb +1 -1
- data/lib/move_task.rb +1 -1
- data/lib/object.rb +1 -1
- data/lib/remote_system.rb +2 -2
- data/lib/remove_task.rb +1 -1
- data/lib/renderer.rb +1 -1
- data/lib/renderer_helper.rb +1 -1
- data/lib/rpm.rb +1 -1
- data/lib/rpm_database.rb +1 -1
- data/lib/scope.rb +1 -1
- data/lib/scope_file_store.rb +1 -1
- data/lib/serve_html_task.rb +1 -1
- data/lib/server.rb +32 -2
- data/lib/show_task.rb +1 -1
- data/lib/system.rb +1 -1
- data/lib/system_description.rb +2 -2
- data/lib/system_description_memory_store.rb +1 -1
- data/lib/system_description_store.rb +1 -1
- data/lib/system_file.rb +1 -1
- data/lib/tarball.rb +1 -1
- data/lib/tee_io.rb +39 -0
- data/lib/try.rb +1 -1
- data/lib/ui.rb +1 -1
- data/lib/upgrade_format_task.rb +1 -1
- data/lib/validate_task.rb +1 -1
- data/lib/version.rb +2 -2
- data/lib/workload_mapper.rb +1 -1
- data/lib/workload_mapper_dsl.rb +1 -1
- data/lib/zypper.rb +3 -3
- data/machinery-helper/Rakefile +2 -8
- data/machinery-helper/file_utils.go +28 -0
- data/machinery-helper/file_utils_test.go +21 -0
- data/machinery-helper/machinery_helper.go +121 -8
- data/machinery-helper/machinery_helper_test.go +102 -0
- data/machinery-helper/mountpoints_test.go +33 -33
- data/machinery-helper/version.go +1 -1
- data/man/generated/machinery.1.gz +0 -0
- data/manual/custom_theme/base.html +42 -0
- data/manual/docs/CNAME +1 -0
- data/manual/docs/README.md +128 -0
- data/manual/docs/css/bootstrap.min.css +7 -0
- data/manual/docs/css/custom.css +788 -0
- data/manual/docs/css/fixed-positioning.css +45 -0
- data/manual/docs/custom.css +804 -0
- data/manual/docs/docs.md +7 -0
- data/manual/docs/favicon.png +0 -0
- data/manual/docs/hand3.png +0 -0
- data/manual/docs/img/arrow.png +0 -0
- data/manual/docs/img/background/1.png +0 -0
- data/manual/docs/img/background/2.png +0 -0
- data/manual/docs/img/background/3.png +0 -0
- data/manual/docs/img/background/4.png +0 -0
- data/manual/docs/img/background/5.png +0 -0
- data/manual/docs/img/background/6.png +0 -0
- data/manual/docs/img/background/7.png +0 -0
- data/manual/docs/img/bk-cloud.png +0 -0
- data/manual/docs/img/bk-sec-15.png +0 -0
- data/manual/docs/img/book.png +0 -0
- data/manual/docs/img/configuration-discovery.png +0 -0
- data/manual/docs/img/dot-line-left.png +0 -0
- data/manual/docs/img/dot-line-right.png +0 -0
- data/manual/docs/img/gear.png +0 -0
- data/manual/docs/img/gear2.png +0 -0
- data/manual/docs/img/gear3.png +0 -0
- data/manual/docs/img/hand.png +0 -0
- data/manual/docs/img/hand2.png +0 -0
- data/manual/docs/img/hand3.png +0 -0
- data/manual/docs/img/home2.png +0 -0
- data/manual/docs/img/moustache.png +0 -0
- data/manual/docs/img/navig.png +0 -0
- data/manual/docs/img/philo.png +0 -0
- data/manual/docs/img/service-migration.png +0 -0
- data/manual/docs/img/system-validation.png +0 -0
- data/manual/docs/img/ticket2.png +0 -0
- data/manual/docs/img/usecase-default.png +0 -0
- data/manual/docs/img/usecase1.png +0 -0
- data/manual/docs/img/usecase2.png +0 -0
- data/manual/docs/img/usecase3.png +0 -0
- data/manual/docs/img/usecase4.png +0 -0
- data/manual/docs/img/wheels.png +0 -0
- data/manual/docs/index.html +402 -0
- data/manual/docs/js/bootstrap.min.js +6 -0
- data/manual/docs/js/custom.js +148 -0
- data/manual/docs/js/jquery.js +4 -0
- data/manual/docs/js/jquery.nicescroll.min.js +116 -0
- data/manual/docs/js/jquery.pageslide.min.js +11 -0
- data/manual/docs/js/parallaxImg.js +146 -0
- data/manual/docs/js/skrollr.min.js +2 -0
- data/manual/docs/machinery-analyze.1.md +37 -0
- data/manual/docs/machinery-build.1.md +62 -0
- data/manual/docs/machinery-compare.1.md +63 -0
- data/manual/docs/machinery-config.1.md +45 -0
- data/manual/docs/machinery-copy.1.md +31 -0
- data/manual/docs/machinery-deploy.1.md +71 -0
- data/manual/docs/machinery-export-autoyast.1.md +58 -0
- data/manual/docs/machinery-export-kiwi.1.md +38 -0
- data/manual/docs/machinery-inspect-docker.1.md +108 -0
- data/manual/docs/machinery-inspect.1.md +145 -0
- data/manual/docs/machinery-list.1.md +51 -0
- data/manual/docs/machinery-man.1.md +16 -0
- data/manual/docs/machinery-move.1.md +29 -0
- data/manual/docs/machinery-remove.1.md +44 -0
- data/manual/docs/machinery-serve.1.md +45 -0
- data/manual/docs/machinery-show.1.md +63 -0
- data/manual/docs/machinery-upgrade-format.1.md +47 -0
- data/manual/docs/machinery-validate.1.md +34 -0
- data/manual/docs/machinery.ymp +114 -0
- data/manual/docs/machinery_main_general.1.md +139 -0
- data/manual/docs/machinery_main_scopes.1.md +98 -0
- data/manual/docs/machinery_main_usecases.1.md +49 -0
- data/manual/docs/machinery_security_implications.1.md +89 -0
- data/manual/docs/subcommand-template.1.md +46 -0
- data/manual/docs/wheels.png +0 -0
- data/manual/mkdocs.yml +30 -0
- data/manual/site/CNAME +1 -0
- data/manual/site/base.html +42 -0
- data/manual/site/css/bootstrap.min.css +7 -0
- data/manual/site/css/custom.css +788 -0
- data/manual/site/css/fixed-positioning.css +45 -0
- data/manual/site/custom.css +804 -0
- data/manual/site/docs/index.html +144 -0
- data/manual/site/favicon.png +0 -0
- data/manual/site/hand3.png +0 -0
- data/manual/site/img/arrow.png +0 -0
- data/manual/site/img/background/1.png +0 -0
- data/manual/site/img/background/2.png +0 -0
- data/manual/site/img/background/3.png +0 -0
- data/manual/site/img/background/4.png +0 -0
- data/manual/site/img/background/5.png +0 -0
- data/manual/site/img/background/6.png +0 -0
- data/manual/site/img/background/7.png +0 -0
- data/manual/site/img/bk-cloud.png +0 -0
- data/manual/site/img/bk-sec-15.png +0 -0
- data/manual/site/img/book.png +0 -0
- data/manual/site/img/configuration-discovery.png +0 -0
- data/manual/site/img/dot-line-left.png +0 -0
- data/manual/site/img/dot-line-right.png +0 -0
- data/manual/site/img/gear.png +0 -0
- data/manual/site/img/gear2.png +0 -0
- data/manual/site/img/gear3.png +0 -0
- data/manual/site/img/hand.png +0 -0
- data/manual/site/img/hand2.png +0 -0
- data/manual/site/img/hand3.png +0 -0
- data/manual/site/img/home2.png +0 -0
- data/manual/site/img/moustache.png +0 -0
- data/manual/site/img/navig.png +0 -0
- data/manual/site/img/philo.png +0 -0
- data/manual/site/img/service-migration.png +0 -0
- data/manual/site/img/system-validation.png +0 -0
- data/manual/site/img/ticket2.png +0 -0
- data/manual/site/img/usecase-default.png +0 -0
- data/manual/site/img/usecase1.png +0 -0
- data/manual/site/img/usecase2.png +0 -0
- data/manual/site/img/usecase3.png +0 -0
- data/manual/site/img/usecase4.png +0 -0
- data/manual/site/img/wheels.png +0 -0
- data/manual/site/index.html +402 -0
- data/manual/site/js/bootstrap.min.js +6 -0
- data/manual/site/js/custom.js +148 -0
- data/manual/site/js/jquery.js +4 -0
- data/manual/site/js/jquery.nicescroll.min.js +116 -0
- data/manual/site/js/jquery.pageslide.min.js +11 -0
- data/manual/site/js/parallaxImg.js +146 -0
- data/manual/site/js/skrollr.min.js +2 -0
- data/manual/site/machinery-analyze.1/index.html +167 -0
- data/manual/site/machinery-build.1/index.html +198 -0
- data/manual/site/machinery-compare.1/index.html +200 -0
- data/manual/site/machinery-config.1/index.html +175 -0
- data/manual/site/machinery-copy.1/index.html +164 -0
- data/manual/site/machinery-deploy.1/index.html +200 -0
- data/manual/site/machinery-export-autoyast.1/index.html +188 -0
- data/manual/site/machinery-export-kiwi.1/index.html +169 -0
- data/manual/site/machinery-inspect-docker.1/index.html +242 -0
- data/manual/site/machinery-inspect.1/index.html +283 -0
- data/manual/site/machinery-list.1/index.html +180 -0
- data/manual/site/machinery-man.1/index.html +148 -0
- data/manual/site/machinery-move.1/index.html +162 -0
- data/manual/site/machinery-remove.1/index.html +175 -0
- data/manual/site/machinery-serve.1/index.html +174 -0
- data/manual/site/machinery-show.1/index.html +199 -0
- data/manual/site/machinery-upgrade-format.1/index.html +173 -0
- data/manual/site/machinery-validate.1/index.html +161 -0
- data/manual/site/machinery.ymp +114 -0
- data/manual/site/machinery_main_general.1/index.html +260 -0
- data/manual/site/machinery_main_scopes.1/index.html +242 -0
- data/manual/site/machinery_main_usecases.1/index.html +182 -0
- data/manual/site/machinery_security_implications.1/index.html +223 -0
- data/manual/site/mkdocs/js/lunr-0.5.7.min.js +7 -0
- data/manual/site/mkdocs/js/mustache.min.js +1 -0
- data/manual/site/mkdocs/js/require.js +36 -0
- data/manual/site/mkdocs/js/search-results-template.mustache +4 -0
- data/manual/site/mkdocs/js/search.js +88 -0
- data/manual/site/mkdocs/js/text.js +390 -0
- data/manual/site/mkdocs/search_index.json +824 -0
- data/manual/site/sitemap.xml +152 -0
- data/manual/site/wheels.png +0 -0
- data/plugins/changed_managed_files/changed_managed_files_inspector.rb +1 -1
- data/plugins/changed_managed_files/changed_managed_files_model.rb +1 -1
- data/plugins/changed_managed_files/changed_managed_files_renderer.rb +1 -1
- data/plugins/changed_managed_files/schema/system-description-changed-managed-files.schema-v7.json +160 -0
- data/plugins/config_files/config_files_inspector.rb +1 -1
- data/plugins/config_files/config_files_model.rb +1 -1
- data/plugins/config_files/config_files_renderer.rb +1 -1
- data/plugins/config_files/schema/system-description-config-files.schema-v7.json +160 -0
- data/plugins/environment/environment_inspector.rb +1 -1
- data/plugins/environment/environment_model.rb +1 -1
- data/plugins/environment/schema/system-description-environment.schema-v7.json +17 -0
- data/plugins/groups/groups_inspector.rb +1 -1
- data/plugins/groups/groups_model.rb +1 -1
- data/plugins/groups/groups_renderer.rb +1 -1
- data/plugins/groups/schema/system-description-groups.schema-v7.json +49 -0
- data/plugins/os/os_inspector.rb +1 -1
- data/plugins/os/os_model.rb +1 -1
- data/plugins/os/os_renderer.rb +1 -1
- data/plugins/os/schema/system-description-os.schema-v7.json +21 -0
- data/plugins/packages/packages_inspector.rb +1 -1
- data/plugins/packages/packages_model.rb +1 -1
- data/plugins/packages/packages_renderer.rb +1 -1
- data/plugins/packages/schema/system-description-packages.schema-v7.json +115 -0
- data/plugins/patterns/patterns_inspector.rb +6 -6
- data/plugins/patterns/patterns_model.rb +1 -1
- data/plugins/patterns/patterns_renderer.rb +1 -1
- data/plugins/patterns/schema/system-description-patterns.schema-v7.json +58 -0
- data/plugins/repositories/repositories_inspector.rb +16 -16
- data/plugins/repositories/repositories_model.rb +1 -1
- data/plugins/repositories/repositories_renderer.rb +1 -1
- data/plugins/repositories/schema/system-description-repositories.schema-v7.json +165 -0
- data/plugins/services/schema/system-description-services.schema-v7.json +93 -0
- data/plugins/services/services_inspector.rb +1 -1
- data/plugins/services/services_model.rb +1 -1
- data/plugins/services/services_renderer.rb +1 -1
- data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v6.json +19 -61
- data/plugins/unmanaged_files/schema/system-description-unmanaged-files.schema-v7.json +124 -0
- data/plugins/unmanaged_files/unmanaged_files_inspector.rb +21 -436
- data/plugins/unmanaged_files/unmanaged_files_model.rb +2 -2
- data/plugins/unmanaged_files/unmanaged_files_renderer.rb +2 -2
- data/plugins/users/schema/system-description-users.schema-v7.json +86 -0
- data/plugins/users/users_inspector.rb +1 -1
- data/plugins/users/users_model.rb +1 -1
- data/plugins/users/users_renderer.rb +1 -1
- data/schema/migrations/migrate1to2.rb +1 -1
- data/schema/migrations/migrate6to7.rb +38 -0
- data/schema/system-description-global.schema-v7.json +43 -0
- data/tools/go.rb +92 -0
- data/tools/helper_builder.rb +16 -49
- metadata +182 -6
- data/man/generated/machinery.1.html +0 -1399
data/lib/system_description.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2016 SUSE LLC
|
2
2
|
#
|
3
3
|
# This program is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of version 3 of the GNU General Public License as
|
@@ -26,7 +26,7 @@
|
|
26
26
|
# The sub directories storing the data for specific scopes are handled by the
|
27
27
|
# ScopeFileStore class.
|
28
28
|
class SystemDescription < Machinery::Object
|
29
|
-
CURRENT_FORMAT_VERSION =
|
29
|
+
CURRENT_FORMAT_VERSION = 7
|
30
30
|
EXTRACTABLE_SCOPES = [
|
31
31
|
"changed_managed_files",
|
32
32
|
"config_files",
|
data/lib/system_file.rb
CHANGED
data/lib/tarball.rb
CHANGED
data/lib/tee_io.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# Copyright (c) 2013-2016 SUSE LLC
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or
|
4
|
+
# modify it under the terms of version 3 of the GNU General Public License as
|
5
|
+
# published by the Free Software Foundation.
|
6
|
+
#
|
7
|
+
# This program is distributed in the hope that it will be useful,
|
8
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
9
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
10
|
+
# GNU General Public License for more details.
|
11
|
+
#
|
12
|
+
# You should have received a copy of the GNU General Public License
|
13
|
+
# along with this program; if not, contact SUSE LLC.
|
14
|
+
#
|
15
|
+
# To contact SUSE about this file by physical or electronic mail,
|
16
|
+
# you may find current contact information at www.suse.com
|
17
|
+
|
18
|
+
# = TeeIO
|
19
|
+
#
|
20
|
+
# Class to allow the storage and forwarding of input at the same time
|
21
|
+
# For example if stderr output should be handled by our code but at the
|
22
|
+
# same time be put out directly
|
23
|
+
#
|
24
|
+
# To prevent for example double error messages data can be filtered
|
25
|
+
# before being passed on to the io_object
|
26
|
+
# Only the data passed along is filtered, not the data stored in this
|
27
|
+
# IO object.
|
28
|
+
class TeeIO < StringIO
|
29
|
+
def initialize(io_object, io_filter = [])
|
30
|
+
super()
|
31
|
+
@io_object = io_object
|
32
|
+
@io_filter = Array(io_filter)
|
33
|
+
end
|
34
|
+
|
35
|
+
def write(data)
|
36
|
+
super
|
37
|
+
@io_object.puts(data) unless @io_filter.include?(data)
|
38
|
+
end
|
39
|
+
end
|
data/lib/try.rb
CHANGED
data/lib/ui.rb
CHANGED
data/lib/upgrade_format_task.rb
CHANGED
data/lib/validate_task.rb
CHANGED
data/lib/version.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2016 SUSE LLC
|
2
2
|
#
|
3
3
|
# This program is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of version 3 of the GNU General Public License as
|
@@ -17,6 +17,6 @@
|
|
17
17
|
|
18
18
|
module Machinery
|
19
19
|
|
20
|
-
VERSION = "1.
|
20
|
+
VERSION = "1.18.0"
|
21
21
|
|
22
22
|
end
|
data/lib/workload_mapper.rb
CHANGED
data/lib/workload_mapper_dsl.rb
CHANGED
data/lib/zypper.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2016 SUSE LLC
|
2
2
|
#
|
3
3
|
# This program is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of version 3 of the GNU General Public License as
|
@@ -76,8 +76,8 @@ class Zypper
|
|
76
76
|
def download_package(package)
|
77
77
|
raw_xml = call_zypper "-x", "download", package, stdout: :capture
|
78
78
|
|
79
|
-
xml =
|
80
|
-
xml.
|
79
|
+
xml = REXML::Document.new(raw_xml)
|
80
|
+
xml.elements["//localfile"].attributes["path"]
|
81
81
|
end
|
82
82
|
|
83
83
|
def version
|
data/machinery-helper/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (c) 2013-
|
1
|
+
# Copyright (c) 2013-2016 SUSE LLC
|
2
2
|
#
|
3
3
|
# This program is free software; you can redistribute it and/or
|
4
4
|
# modify it under the terms of version 3 of the GNU General Public License as
|
@@ -17,7 +17,7 @@
|
|
17
17
|
|
18
18
|
require_relative "../tools/helper_builder"
|
19
19
|
|
20
|
-
task :default => "
|
20
|
+
task :default => "build"
|
21
21
|
|
22
22
|
HELPER_DIR = File.expand_path(File.dirname(__FILE__))
|
23
23
|
|
@@ -26,9 +26,3 @@ task :build do
|
|
26
26
|
helper_builder = HelperBuilder.new(HELPER_DIR)
|
27
27
|
raise "Error: Build of Machinery helper failed" if !helper_builder.run_build
|
28
28
|
end
|
29
|
-
|
30
|
-
desc "Don't fail on build errors"
|
31
|
-
task :try_build do
|
32
|
-
helper_builder = HelperBuilder.new(HELPER_DIR)
|
33
|
-
helper_builder.run_build
|
34
|
-
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"bytes"
|
5
|
+
"log"
|
6
|
+
"os/exec"
|
7
|
+
"strings"
|
8
|
+
)
|
9
|
+
|
10
|
+
var statFile = func(path string) string {
|
11
|
+
cmd := exec.Command("stat", "-c", "%U:%G", path)
|
12
|
+
var out bytes.Buffer
|
13
|
+
cmd.Stdout = &out
|
14
|
+
err := cmd.Run()
|
15
|
+
if err != nil {
|
16
|
+
log.Fatal(err)
|
17
|
+
}
|
18
|
+
|
19
|
+
return strings.Trim(out.String(), "\n")
|
20
|
+
}
|
21
|
+
|
22
|
+
func getFileOwnerGroup(path string) (user, group string) {
|
23
|
+
split := strings.Split(statFile(path), ":")
|
24
|
+
user = split[0]
|
25
|
+
group = split[1]
|
26
|
+
|
27
|
+
return
|
28
|
+
}
|
@@ -0,0 +1,21 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import (
|
4
|
+
"testing"
|
5
|
+
)
|
6
|
+
|
7
|
+
func TestGetFileOwnerGroup(t *testing.T) {
|
8
|
+
statFile = func(path string) string {
|
9
|
+
return "foo:bar"
|
10
|
+
}
|
11
|
+
path := "/etc/passwd"
|
12
|
+
|
13
|
+
owner, group := getFileOwnerGroup(path)
|
14
|
+
|
15
|
+
if owner != "foo" {
|
16
|
+
t.Errorf("GetFileOwner('%v') = '%v', want '%v'", path, owner, "foo")
|
17
|
+
}
|
18
|
+
if group != "bar" {
|
19
|
+
t.Errorf("GetFileOwner('%v') = '%v', want '%v'", path, owner, "bar")
|
20
|
+
}
|
21
|
+
}
|
@@ -29,10 +29,24 @@ import (
|
|
29
29
|
"path/filepath"
|
30
30
|
"regexp"
|
31
31
|
"sort"
|
32
|
+
"strconv"
|
32
33
|
"strings"
|
33
34
|
"unicode/utf8"
|
34
35
|
)
|
35
36
|
|
37
|
+
// An UnmanagedFile represents an unmanaged file in the system description.
|
38
|
+
type UnmanagedFile struct {
|
39
|
+
Name string `json:"name"`
|
40
|
+
User string `json:"user,omitempty"`
|
41
|
+
Group string `json:"group,omitempty"`
|
42
|
+
Type string `json:"type"`
|
43
|
+
Mode string `json:"mode,omitempty"`
|
44
|
+
Files *int `json:"files,omitempty"`
|
45
|
+
FilesValue int `json:"-"`
|
46
|
+
Size *int64 `json:"size,omitempty"`
|
47
|
+
SizeValue int64 `json:"-"`
|
48
|
+
}
|
49
|
+
|
36
50
|
func getDpkgContent() []string {
|
37
51
|
cmd := exec.Command("bash", "-c", "dpkg --get-selections | grep -v deinstall | awk '{print $1}'")
|
38
52
|
var out bytes.Buffer
|
@@ -193,6 +207,19 @@ var readDir = func(dir string) ([]os.FileInfo, error) {
|
|
193
207
|
return ioutil.ReadDir(dir)
|
194
208
|
}
|
195
209
|
|
210
|
+
var dirSize = func(path string) int64 {
|
211
|
+
dir, err := os.Open(path)
|
212
|
+
if err != nil {
|
213
|
+
log.Fatal(err)
|
214
|
+
}
|
215
|
+
stat, err := dir.Stat()
|
216
|
+
if err != nil {
|
217
|
+
log.Fatal(err)
|
218
|
+
}
|
219
|
+
dir.Close()
|
220
|
+
return stat.Size()
|
221
|
+
}
|
222
|
+
|
196
223
|
func hasManagedDirs(dir string, rpmDirs map[string]bool) bool {
|
197
224
|
for rpmDir := range rpmDirs {
|
198
225
|
if strings.HasPrefix(rpmDir, dir+"/") {
|
@@ -236,11 +263,91 @@ func findUnmanagedFiles(dir string, rpmFiles map[string]string, rpmDirs map[stri
|
|
236
263
|
}
|
237
264
|
}
|
238
265
|
|
266
|
+
func amendMode(entry *UnmanagedFile, perm os.FileMode) {
|
267
|
+
if entry.Type == "link" {
|
268
|
+
return
|
269
|
+
}
|
270
|
+
|
271
|
+
result := int64(perm.Perm())
|
272
|
+
|
273
|
+
if perm&os.ModeSticky > 0 {
|
274
|
+
result |= 01000
|
275
|
+
}
|
276
|
+
if perm&os.ModeSetuid > 0 {
|
277
|
+
result |= 04000
|
278
|
+
}
|
279
|
+
if perm&os.ModeSetgid > 0 {
|
280
|
+
result |= 02000
|
281
|
+
}
|
282
|
+
entry.Mode = strconv.FormatInt(result, 8)
|
283
|
+
|
284
|
+
// Pad mode string to a length of three
|
285
|
+
for len(entry.Mode) < 3 {
|
286
|
+
entry.Mode = "0" + entry.Mode
|
287
|
+
}
|
288
|
+
}
|
289
|
+
|
290
|
+
func dirInfo(path string) (size int64, fileCount int) {
|
291
|
+
files, _ := readDir(path)
|
292
|
+
|
293
|
+
size = int64(0)
|
294
|
+
fileCount = len(files)
|
295
|
+
for _, f := range files {
|
296
|
+
if f.IsDir() {
|
297
|
+
if _, ok := IgnoreList[path + f.Name()]; !ok {
|
298
|
+
subSize, subCount := dirInfo(path + f.Name() + "/")
|
299
|
+
size += subSize
|
300
|
+
fileCount += subCount
|
301
|
+
}
|
302
|
+
} else if f.Mode()&os.ModeSymlink != os.ModeSymlink {
|
303
|
+
size += f.Size()
|
304
|
+
}
|
305
|
+
}
|
306
|
+
|
307
|
+
return
|
308
|
+
}
|
309
|
+
|
310
|
+
func amendSize(entry *UnmanagedFile, size int64) {
|
311
|
+
if entry.Type == "file" {
|
312
|
+
entry.SizeValue = size
|
313
|
+
entry.Size = &entry.SizeValue
|
314
|
+
} else if entry.Type == "dir" {
|
315
|
+
size, files := dirInfo(entry.Name)
|
316
|
+
entry.SizeValue = size
|
317
|
+
entry.Size = &entry.SizeValue
|
318
|
+
entry.FilesValue = files
|
319
|
+
entry.Files = &entry.FilesValue
|
320
|
+
}
|
321
|
+
}
|
322
|
+
|
323
|
+
func amendPathAttributes(entry *UnmanagedFile, fileType string) {
|
324
|
+
if fileType != "link" {
|
325
|
+
file, err := os.Open(entry.Name)
|
326
|
+
if err != nil {
|
327
|
+
log.Fatal(err)
|
328
|
+
}
|
329
|
+
fi, err := file.Stat()
|
330
|
+
if err != nil {
|
331
|
+
log.Fatal(err)
|
332
|
+
}
|
333
|
+
file.Close()
|
334
|
+
|
335
|
+
amendMode(entry, fi.Mode())
|
336
|
+
amendSize(entry, fi.Size())
|
337
|
+
}
|
338
|
+
|
339
|
+
entry.User, entry.Group = getFileOwnerGroup(entry.Name)
|
340
|
+
}
|
341
|
+
|
239
342
|
func printVersion() {
|
240
343
|
fmt.Println("Version:", VERSION)
|
241
344
|
os.Exit(0)
|
242
345
|
}
|
243
346
|
|
347
|
+
// IgnoreList includes mounts and any other file type that will be ignored when
|
348
|
+
// evaluating the unmanaged files in a system.
|
349
|
+
var IgnoreList = map[string]bool{}
|
350
|
+
|
244
351
|
func main() {
|
245
352
|
// check for tar extraction
|
246
353
|
if len(os.Args) >= 2 {
|
@@ -253,6 +360,7 @@ func main() {
|
|
253
360
|
|
254
361
|
// parse CLI arguments
|
255
362
|
var versionFlag = flag.Bool("version", false, "shows the version number")
|
363
|
+
var extractMetadataFlag = flag.Bool("extract-metadata", false, "extracts metadata without extracting files")
|
256
364
|
flag.Parse()
|
257
365
|
|
258
366
|
// show version
|
@@ -264,14 +372,14 @@ func main() {
|
|
264
372
|
unmanagedFiles := make(map[string]string)
|
265
373
|
thisBinary, _ := filepath.Abs(os.Args[0])
|
266
374
|
|
267
|
-
|
375
|
+
IgnoreList = map[string]bool{
|
268
376
|
thisBinary: true,
|
269
377
|
}
|
270
378
|
for _, mount := range RemoteMounts() {
|
271
|
-
|
379
|
+
IgnoreList[mount] = true
|
272
380
|
}
|
273
381
|
for _, mount := range SpecialMounts() {
|
274
|
-
|
382
|
+
IgnoreList[mount] = true
|
275
383
|
}
|
276
384
|
|
277
385
|
for _, mount := range RemoteMounts() {
|
@@ -279,7 +387,7 @@ func main() {
|
|
279
387
|
}
|
280
388
|
|
281
389
|
managedFiles, managedDirs := getManagedFiles()
|
282
|
-
findUnmanagedFiles("/", managedFiles, managedDirs, unmanagedFiles,
|
390
|
+
findUnmanagedFiles("/", managedFiles, managedDirs, unmanagedFiles, IgnoreList)
|
283
391
|
|
284
392
|
files := make([]string, len(unmanagedFiles))
|
285
393
|
i := 0
|
@@ -289,11 +397,16 @@ func main() {
|
|
289
397
|
}
|
290
398
|
sort.Strings(files)
|
291
399
|
|
292
|
-
unmanagedFilesMap := make([]
|
400
|
+
unmanagedFilesMap := make([]UnmanagedFile, len(unmanagedFiles))
|
293
401
|
for j := range files {
|
294
|
-
entry :=
|
295
|
-
entry
|
296
|
-
entry
|
402
|
+
entry := UnmanagedFile{}
|
403
|
+
entry.Name = files[j]
|
404
|
+
entry.Type = unmanagedFiles[files[j]]
|
405
|
+
|
406
|
+
if *extractMetadataFlag {
|
407
|
+
amendPathAttributes(&entry, unmanagedFiles[files[j]])
|
408
|
+
}
|
409
|
+
|
297
410
|
unmanagedFilesMap[j] = entry
|
298
411
|
}
|
299
412
|
|
@@ -190,3 +190,105 @@ func TestSubdirIsNotAccidentallyConsideredManaged(t *testing.T) {
|
|
190
190
|
t.Errorf("hasManagedDirs() = '%v', want '%v'", hasDirs, want)
|
191
191
|
}
|
192
192
|
}
|
193
|
+
|
194
|
+
func TestAmendMode(t *testing.T) {
|
195
|
+
entry := UnmanagedFile{Type: "file"}
|
196
|
+
|
197
|
+
amendMode(&entry, os.FileMode(0777))
|
198
|
+
want := "777"
|
199
|
+
if entry.Mode != want {
|
200
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
201
|
+
}
|
202
|
+
|
203
|
+
amendMode(&entry, os.FileMode(0222))
|
204
|
+
want = "222"
|
205
|
+
if entry.Mode != want {
|
206
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
207
|
+
}
|
208
|
+
|
209
|
+
perm := os.FileMode(0222 | os.ModeSticky)
|
210
|
+
amendMode(&entry, perm)
|
211
|
+
want = "1222"
|
212
|
+
if entry.Mode != want {
|
213
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
214
|
+
}
|
215
|
+
|
216
|
+
perm = os.FileMode(0222 | os.ModeSetuid)
|
217
|
+
amendMode(&entry, perm)
|
218
|
+
want = "4222"
|
219
|
+
if entry.Mode != want {
|
220
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
221
|
+
}
|
222
|
+
|
223
|
+
perm = os.FileMode(0555 | os.ModeSticky | os.ModeSetgid)
|
224
|
+
amendMode(&entry, perm)
|
225
|
+
want = "3555"
|
226
|
+
if entry.Mode != want {
|
227
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
228
|
+
}
|
229
|
+
|
230
|
+
perm = os.FileMode(0000)
|
231
|
+
amendMode(&entry, perm)
|
232
|
+
want = "000"
|
233
|
+
if entry.Mode != want {
|
234
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
235
|
+
}
|
236
|
+
|
237
|
+
perm = os.FileMode(0044)
|
238
|
+
amendMode(&entry, perm)
|
239
|
+
want = "044"
|
240
|
+
if entry.Mode != want {
|
241
|
+
t.Errorf("amendMode() = '%v', want '%v", entry.Mode, want)
|
242
|
+
}
|
243
|
+
|
244
|
+
entry = UnmanagedFile{Type: "link"}
|
245
|
+
amendMode(&entry, perm)
|
246
|
+
if entry.Mode != "" {
|
247
|
+
t.Errorf("links should not have a mode")
|
248
|
+
}
|
249
|
+
}
|
250
|
+
|
251
|
+
func TestAmendSize(t *testing.T) {
|
252
|
+
entry := UnmanagedFile{Type: "link"}
|
253
|
+
|
254
|
+
amendSize(&entry, 0)
|
255
|
+
if entry.Size != nil {
|
256
|
+
t.Errorf("Link should not get a size")
|
257
|
+
}
|
258
|
+
|
259
|
+
entry = UnmanagedFile{Type: "file"}
|
260
|
+
|
261
|
+
amendSize(&entry, 0)
|
262
|
+
if *entry.Size != 0 {
|
263
|
+
t.Errorf("File should get a size")
|
264
|
+
}
|
265
|
+
|
266
|
+
entry = UnmanagedFile{Name: "/opt/", Type: "dir"}
|
267
|
+
readDir = func(dir string) ([]os.FileInfo, error) {
|
268
|
+
dirs := make([]os.FileInfo, 0, 1)
|
269
|
+
switch dir {
|
270
|
+
// 0 is used as a type to define a Normal file
|
271
|
+
case "/opt/":
|
272
|
+
dirs = append(dirs, fakefileinfo.New("foo", int64(12), 0, time.Now(), false, nil))
|
273
|
+
dirs = append(dirs, fakefileinfo.New("bar", int64(12), 0, time.Now(), false, nil))
|
274
|
+
dirs = append(dirs, fakefileinfo.New("baz", int64(4096), os.ModeDir, time.Now(), true, nil))
|
275
|
+
dirs = append(dirs, fakefileinfo.New("foo-link", int64(8), os.ModeSymlink, time.Now(), false, nil))
|
276
|
+
case "/opt/baz/":
|
277
|
+
dirs = append(dirs, fakefileinfo.New("foo", int64(12), 0, time.Now(), false, nil))
|
278
|
+
dirs = append(dirs, fakefileinfo.New("bar", int64(12), 0, time.Now(), false, nil))
|
279
|
+
}
|
280
|
+
return dirs, nil
|
281
|
+
}
|
282
|
+
dirSize = func(path string) int64 {
|
283
|
+
return 4096
|
284
|
+
}
|
285
|
+
amendSize(&entry, 0)
|
286
|
+
want := int64(48) // 4 files (12 bytes each)
|
287
|
+
if *entry.Size != want {
|
288
|
+
t.Errorf("entry.Size = '%v', want '%v'", *entry.Size, want)
|
289
|
+
}
|
290
|
+
wantFiles := 6
|
291
|
+
if *entry.Files != wantFiles {
|
292
|
+
t.Errorf("entry.Files = '%v', want '%v'", *entry.Files, wantFiles)
|
293
|
+
}
|
294
|
+
}
|