diff --git a/slide-deck.html b/slide-deck.html index 8eb669e..0329b50 100644 --- a/slide-deck.html +++ b/slide-deck.html @@ -7,9 +7,380 @@ - + + +
@@ -19,11 +390,11 @@classes
bodies default to namespace scopeclasses
bodies (define classes based on promise results default to namespace scope)
-Pro Tip: Use bundle
scoped classes whenever possible.
-
bundle agent bundle0 +{ + classes: + "I_will_be_bundle_scoped" + expression => "any"; +} +bundle common bundle1 +{ + classes: + "I_will_be_namespace_scoped" + expression => "any"; +} ++
bundle
scoped classes whenever possible.bundle agent sshd_config +{ + services: + "sshd" + service_policy => "start"; + + sshd_config_repaired.proposed_sshd_config_validated:: + "sshd" + service_policy => "restart"; +} ++
bundle agent main @@ -2701,8 +3180,8 @@Define custom classes by expression
bundle agent main @@ -2729,8 +3208,8 @@Define custom classes by promise outcome
bundle agent main @@ -2762,8 +3241,8 @@Example - traditional class expressions
-- Example - restrict individual promises with if and unless
++ Example - restrict individual promises with if and unless
bundle agent main @@ -2797,8 +3276,8 @@Example - restrict individual promises with if and unless -
- Example - variable class expressions
++ Example - variable class expressions
bundle agent main @@ -2841,8 +3320,8 @@Example - variable class expressions
-- Functions that return "context"
++ Functions that return "context"
cf-promises --syntax-description json | jq '.functions | \ @@ -2856,8 +3335,8 @@Functions that return "context"
-- Pop Quiz
++ Pop Quiz
- What types of classes are there?
@@ -2909,12 +3388,12 @@Pop Quiz
- - Variables & Data Types
++ -Variables & Data Types
- Variable Scoping
++ -Variable Scoping
- All variables are globally accessible
- @@ -2928,8 +3407,8 @@
$(variable)
,@(list or data container)
Variable Scoping
- Datatypes
++ -Datatypes
- string, int, real
- slist, ilist, rlist
@@ -2938,8 +3417,8 @@Datatypes
- Example - strings
++ Example - strings
bundle agent main @@ -2982,8 +3461,8 @@-Example - strings
- Example - numbers
++ Example - numbers
bundle agent main @@ -3046,9 +3525,20 @@Example - numbers
-
+inf
- a constant representing an "unlimited", value.
+inf
- a constant representing an "unlimited", value. But, not in all cases.
+https://docs.cfengine.com/docs/master/reference-language-concepts-variables.html#scalar-variables +
+ ++inf is a special value that in the code corresponds to the magic number of 999999999 (nine nines). Thus any function that accepts a number, can accept inf without a problem. Keep in mind though that you can get a higher number if you set the upper limit manually, but that's almost never a problem. +
+ ++For a few functions inf is being treated specially and truly means "there is no limit" instead of "nine nines limit". This is the case for the maxbytes parameter and applies to most read* functions. +
@@ -3080,7 +3570,7 @@Example - numbers
"inf ($(inf_is)) < biggest_int ($(biggest_int))" if => isgreaterthan( $(biggest_int), $(inf_is) ); - "$(biggest_int) is $(with) greater than $(inf_is)" + "biggest_int ($(biggest_int)) is $(with) greater than inf ($(inf_is))" with => format( "%0.0f", eval( "$(biggest_int)-$(inf_is)", math, infix)); } bundle agent __main__ @@ -3092,12 +3582,32 @@Example - numbers
R: inf (999999999) < biggest_int (99999999999) -R: 99999999999 is 99000000000 greater than 999999999 +R: biggest_int (99999999999) is 99000000000 greater than inf (999999999)+ + + -- Example - lists
++ Example - lists
bundle agent main @@ -3129,7 +3639,7 @@Example - lists
- -+R: var1 = '1' R: var1 = '2' R: var1 = '3' @@ -3151,8 +3661,8 @@Example - lists
- Example - list iteration (loops)
++ Example - list iteration (loops)
bundle agent main @@ -3173,7 +3683,7 @@-Example - list iteration (loops)
- -+R: 1 R: 2 R: 3 @@ -3201,8 +3711,8 @@Example - list iteration (loops)
- Example - "Classic" Arrays
++ -Example - "Classic" Arrays
bundle agent main @@ -3232,8 +3742,8 @@-Example - "Classic" Arrays
- Example - data containers
++ Example - data containers
+ +bundle agent main @@ -3257,20 +3767,48 @@Example - data containers
- -+R: URL = 'https://mirror.int.cfengine.com/RHEL6/updates'- Differences between "Classic Arrays" and "Data containers"
++ +Associative Arrays vs Data containers
++
+ +- Data containers defined as a single variable
+- Associative Arrays aka Classic arrays +
+ ++
- collection of individual variables
+- cleared at the start of each bundle evaluation
+ ++ -Example Associative Arrays vs Data containers
bundle agent main @@ -3287,22 +3828,25 @@Differences between "Classic Arrays" and "Data containers" vars: "ClassicArray[key]" string => "value"; "ClassicArray[deep]" slist => { "list" }; + "ClassicArray[nevermind]" + string => "value", + if => "notdefined"; "DataContainer" data => '{ "key": "value", "deep": [ "list" ] }'; reports: "ClassicArray:$(with)" - with => string_mustache( "{{%-top-}}", ClassicArray); + with => storejson( ClassicArray); "DataContainer:$(with)" - with => string_mustache( "{{%-top-}}", DataContainer); + with => storejson( DataContainer); }
- - ++ -Example Associative Arrays vs Data containers output
+R: ClassicArray:{ "deep": [ "list" @@ -3318,8 +3862,8 @@Differences between "Classic Arrays" and "Data containers"
- Pop Quiz
++ Pop Quiz
- Which component makes changes to your system?
@@ -3368,11 +3912,13 @@Pop Quiz
+ +- - Policy Examples
++ -Policy Examples
- -Enable services_autorun
-++ -Enable services_autorun
+[root@hub masterfiles]# cat > def.json <<EOF { "vars": { @@ -3419,8 +3965,8 @@Enable services_autorun
- Create a file
++ -Create a file
examples/00-20-example-create_file.cf
@@ -3463,8 +4009,8 @@Create a file
- Update file
++ Update file
examples/00-20-example-update_file.cf
@@ -3518,8 +4064,8 @@Update file
- Make sure a package is installed and service running
++ -Make sure a package is installed and service running
examples/00-20-example-package_and_service.cf
@@ -3599,8 +4145,8 @@Make sure a package is installed and service running
- Competing implementations of packages promises
++ -Competing implementations of packages promises
- methods (legacy) vs modules (modern)
@@ -3633,8 +4179,8 @@Competing implementations of packages promises
- Classify role based on hostname
++ Classify role based on hostname
examples/00-20-example-classes-role_by_hostname.cf
@@ -3663,8 +4209,8 @@Classify role based on hostname
- Classify geographic location by network
++ -Classify geographic location by network
examples/00-20-example-classes-geographic_location_by_network
@@ -3767,8 +4313,8 @@Classify geographic location by network
- Manage key value entries in a config file
++ Manage key value entries in a config file
examples/00-20-example-key_value_config.cf
@@ -3859,7 +4405,7 @@Manage key value entries in a config file
- -+[root@hub masterfiles]# cf-agent -KID DEBUG_ssh_config,DEBUG_ssh_config_manage_kv info: Installing cfe_internal_non_existing_package... R: DEBUG ssh_config: PermitRootLogin = 'no' @@ -3877,8 +4423,8 @@Manage key value entries in a config file
- Templating a file with mustache
++ -Templating a file with mustache
examples/00-20-example-mustache_template_inline_using_datastate.cf
@@ -3917,8 +4463,8 @@Templating a file with mustache
- Mustache extensions
++ -Mustache extensions
-top-
data handed to the templating engine- @@ -4036,8 +4582,8 @@
@
Currently iterated keyMustache extensions
- Inventory SSH Host Keys
++ Inventory SSH Host Keys
examples/inventory-ssh-host-keys.cf
@@ -4075,7 +4621,7 @@Inventory SSH Host Keys
- -+R: /etc/ssh/ssh_host_ed25519_key.pub type: ed25519 fingerprint: SHA256:NA04HcvSPZ/wAp/vJUIcOV799ImTWnbFEX0R9R2SXUI @@ -4091,8 +4637,8 @@Inventory SSH Host Keys
- Interacting with APIs from within CFEngine Policy
++ Interacting with APIs from within CFEngine Policy
- +# cf-agent --no-lock --log-level info --file examples/example-url_get-wtfismyip-v0.cf R: { "content": "{\n \"YourFuckingIPAddress\": \"24.143.34.87\",\n \"YourFuckingLocation\": \"Tonganoxie, KS, United States\",\n \"YourFuckingHostname\": \"24-143-34-87-dynamic.midco.net\",\n \"YourFuckingISP\": \"Midco\",\n \"YourFuckingTorExit\": false,\n \"YourFuckingCountryCode\": \"US\"\n}\n", @@ -4208,27 +4754,27 @@Interacting with APIs from within CFEngine Policy
- - -Policy Exercises
-++ -Policy Exercises
+- Edit a file
++ -Edit a file
Write a policy that populates
/etc/issue
with legaleze.- Create local users
++ -Create local users
Write a policy that creates at least 2 users.
- Inventory the local users
++ Inventory the local users
Tag the variable(s) that contain the usernames you promised for inventory.
@@ -4240,8 +4786,8 @@Inventory the local users
- Create a file
++ -Create a file
Write a policy that ensures
@@ -4251,96 +4797,40 @@/etc/cron.allow
is populated with one of the previously created users allowed to have cron jobs.Create a file
- Inventory users in /etc/cron.allow
++ -Inventory users in /etc/cron.allow
Inventory the users listed in
/etc/cron.allow
- Enable sshd banner
++ -Enable sshd banner
Write a policy that enables the ssh banner and directs it to
/etc/issue
. sshd should be restarted after changing its configuration.- -Multiple outcomes
-- -- -touch /tmp/immutable -sudo chattr +i /tmp/immutable --- - -- -- -bundle agent example_multiple_outcomes -{ - files: - "/tmp/immutable" - create => "true", - edit_line => example_edit_line, - classes => results("bundle", "my_id"); - - vars: - "classes" slist => classesmatching(".*my_id.*"); - - reports: - "Found Class = '$(classes)'"; -} - -bundle edit_line example_edit_line -{ - insert_lines: - "I want to edit an immutable file"; -} -bundle agent __main__{methods:"example_multiple_outcomes";} --- - - info: Inserted the promised line 'I want to edit an immutable file' into '/tmp/immutable' after locator - info: insert_lines promise 'I want to edit an immutable file' repaired - error: Can't rename '/tmp/immutable.cf-after-edit' to '/tmp/immutable' - so promised edits could not be moved into place. (rename: Operation not permitted) - error: Unable to save file '/tmp/immutable' after editing - error: Errors encountered when actuating files promise '/tmp/immutable' -R: Found Class = 'my_id_failed' -R: Found Class = 'my_id_not_kept' -R: Found Class = 'my_id_error' -R: Found Class = 'my_id_kept' -R: Found Class = 'my_id_reached' - error: Method 'example_multiple_outcomes' failed in some repairs -- --Refer to implementation of the
+results
classes body in the stdlib. -+ -Install ntpd and configure driftfile
++
- Install ntp
+- Ensure service is running
+- Configure path to driftfile
+/var/lib/ntp/drift
?- Make sure service is restarted if configuration file content is altered
-- -+sudo chattr -i /tmp/immutable -sudo rm /tmp/immutable --- Report
++ -Report
Write a policy that defines a name in separate parts (at least 3). Then have CFEngine report the name in a random order.
- Example solution
++ Example solution
- Trigger an action when a file changes
++ -Trigger an action when a file changes
Write policy to monitor a file for change. When a change is seen report
Winner Winner Chicken Dinner
. Manually edit the file, show how cfengine detects and @@ -4380,8 +4870,8 @@Trigger an action when a file changes
- Automatically abort based on file presence
++ -Automatically abort based on file presence
Write a policy that will abort cfengine execution if the file
$(sys.statedir)/abort_agent_execution
exists. @@ -4392,28 +4882,28 @@Automatically abort based on file presence
- Delete file based on age
++ -Delete file based on age
Write a policy that will delete
$(sys.statedir)/abort_agent_execution
if it is older than 1 hour.- Kill a process
++ -Kill a process
Write a policy to kill irssi running on webservers. No need for our webservers to be connected to IRC.
-+cp /bin/sleep /tmp/irssi /tmp/irssi 5000- Building on example-url_get-wtfismyip-v0.cf
++ Building on example-url_get-wtfismyip-v0.cf
- Let's use the response content from the previous example in a template to manage a file.
@@ -4557,8 +5047,8 @@Building on example-url_get-wtfismyip-v0.cf
- - Inventory batteries
++ -Inventory batteries
/sys/class/power_supply/BAT*/capacity
@@ -4572,22 +5062,44 @@
Inventory batteries
- Strip suffixes from a list of filenames
++ +Strip suffixes from a list of filenames
-Given a list of filenames, (
+1.txt
,2.txt
,3.txt
) strip the suffix (.txt
) and get the prefix into a new list. +Given a list of filenames strip the suffix and get the prefix into a new list.+E.g. given a list containing
+ +1.txt
,2.txt
,3.txt
produce a list containing1
,2
,3
. ++ Manage files described by a data container
++ ++[ + { + "name": "/tmp/create-multiple-files-with.content-1.txt", + "content": "Hello CFEngine!" + }, + { + "name": "/tmp/create-multiple-files-with.content-2.txt", + "content": "Bye CFEngine!" + } + ] ++- - Enterprise Reporting
-++ -Enterprise Reporting
+- APIs
++ -APIs
- Host
- Inventory
@@ -4621,8 +5133,8 @@APIs
- Host API
++ -Host API
curl -s -k --user $AUTHUSER:$PASSWORD \ @@ -4664,13 +5176,13 @@Host API
- +Inventory API
-+++ -Inventory API
+- Inventory API attributes
++ -Inventory API attributes
curl -q -k --user $AUTHUSER:$PASSWORD \ @@ -4692,7 +5204,7 @@Inventory API attributes
- -+"Policy Release Id" "EC2 Image ID" "CPU sockets" @@ -4788,8 +5300,8 @@Inventory API attributes
- Inventory API Query
++ -Inventory API Query
curl -q -k --user $AUTHUSER:$PASSWORD \ @@ -4818,8 +5330,8 @@Inventory API Query
- Health API
++ -Health API
curl -s -k --user $AUTHUSER:$PASSWORD \ @@ -4874,8 +5386,8 @@Health API
- Query API
++ Query API
- Base64 encoded query links
++ Base64 encoded query links
+ +Actions
++Actions API enables you to perform specific actions such a requesting report collection and triggering un-scheduled agent runs. +
+ ++Note: Triggered actions (agent run, report collection) will not work for hosts that the hub cannot initiate connections to, e.g. hosts behind NAT. +
+ ++ +Trigger report collection
++ ++ +exec 2>&1 +/var/cfengine/bin/curl \ + --insecure \ + --user admin:admin \ + --write-out "HTTP %{response_code}" \ + --request POST \ + -H 'content-tyupe: application/json' \ + -d '{"hostkey": "SHA=55425b6c6c5fcd1ea7f00cf45736a3acd87a3503dc61abaf268ca59f47fe4a05" }' \ + https://hub.example.com/api/actions/report_collection +: +++Array +HTTP 202 ++ ++ Trigger agent run
++ ++ +exec 2>&1 +/var/cfengine/bin/curl \ + --insecure \ + --user admin:admin \ + --write-out "HTTP %{response_code}" \ + --request POST \ + -H 'content-tyupe: application/json' \ + -d '{"hostkey": "SHA=55425b6c6c5fcd1ea7f00cf45736a3acd87a3503dc61abaf268ca59f47fe4a05" }' \ + https://hub.example.com/api/actions/agent_run +: +++{ +"output" : "", +"exit_code": 0 +} + +HTTP 202 ++ +- - What's New
-++ -What's New
+- Coming up in 3.21…
++ -Coming up in 3.21…
- In 3.20
++ -In 3.20
- Build in Mission Portal
- In 3.19
++ -In 3.19
- Importable Compliance Reports in Mission Portal
- In 3.18
++ -In 3.18
- Host specific data (CMDB) in Mission Portal
- More powerful Augments syntax
@@ -5084,8 +5658,8 @@In 3.18
- In 3.17
++ -In 3.17
- New functions:
@@ -5100,14 +5674,14 @@
In 3.17
- In 3.16
-++ -In 3.16
+- -Components
-++ -Components
+Usage: cf-secret COMMAND [OPTIONS] [FILE] Commands: @@ -5186,8 +5760,8 @@Components
- Promise attributes
++ -Promise attributes
-bundle agent example_file_content @@ -5210,7 +5784,7 @@Promise attributes
+info: Created file '/tmp/hello_string', mode 0600 info: Updated content of '/tmp/hello_string' with content 'Hello from string!' info: files promise '/tmp/hello_string' repaired @@ -5219,8 +5793,8 @@Promise attributes
- Functions
++ Functions
Complementary to new macros:
@@ -5345,8 +5919,8 @@Functions
- Macros
++ -Macros
maximum_version
- @@ -5383,20 +5957,20 @@
else
Macros
- Enterprise Edition
++ -Enterprise Edition
- Compliance Reports
- In 3.15
-++ -In 3.15
+- Functions
++ -Functions
basename()
- @@ -5497,13 +6071,13 @@
read_module_protocol()
Functions
- In 3.14
-++ -In 3.14
+- Functions
++ Functions
- @@ -5568,7 +6142,7 @@
classfiltercsv()
(back-ported to 3.12.1)Functions
- -+R: Filtered data: [ { "Sort": "1", @@ -5594,13 +6168,13 @@Functions
- In 3.13
-++ -In 3.13
+- Functions
++ -Functions
- @@ -5632,13 +6206,13 @@
string_replace()
Functions
- In 3.12
-++ -In 3.12
+- Functions
++ -Functions
- @@ -5673,8 +6247,8 @@
hash_to_int()
Functions
R: 'world' hashed to: 760- Library main bundles
++ Library main bundles
- Default bundle per policy file
- Useful for testing
@@ -5791,7 +6365,7 @@Library main
- -+example_library__main__1.cf example_library__main__2.cf example_library__main__.cf @@ -5859,8 +6433,8 @@Library main
- –log-level option
++ -–log-level option
-bundle agent main @@ -5883,8 +6457,8 @@-–log-level option
- Promise attributes
++ -Promise attributes
copy_from
body attributemissing_ok
allows missing upstream files to be considered promise kept- files promise
@@ -5980,29 +6554,29 @@template_method
accepts inline_mustachePromise attributes
- sys vars
++ -sys vars
- sys.policy_entry*
- In 3.11
-+-+ -In 3.11
+- Promise attributes
++ -Promise attributes
with
- Functions
++ Functions
data_sysctlvalues()
- @@ -6030,7 +6604,7 @@
readenvfile()
Functions
+R: { "abi.vsyscall32": "1", "debug.exception-trace": "1", @@ -15574,7 +16148,7 @@Functions
+R: { "BUG_REPORT_URL": "https://bugs.launchpad.net/ubuntu/", "HOME_URL": "https://www.ubuntu.com/", @@ -15592,13 +16166,13 @@Functions
- -In 3.10
-++ -In 3.10
+- Functions
++ -Functions
getuserinfo()
- @@ -15701,13 +16275,13 @@
isipinsubnet()
Functions
- -In 3.9
-++ -In 3.9
+- Functions
++ -Functions
callstack_callers()
- @@ -15857,13 +16431,13 @@
callstack_promisers()
Functions
- In 3.8
-+-+ -In 3.8
+- Functions
++ Functions
- @@ -15903,13 +16477,13 @@
url_get()
Functions
- - -Special Topics
-+-+ -Special Topics
+- Internal agent upgrade mechanism
++ -Internal agent upgrade mechanism
- Place agent packages in
@@ -15933,13 +16507,13 @@/var/cfengine/master_software_updates/$(sys.flavour)_$(sys.arch)
Internal agent upgrade mechanism
- -Data transformations
-+-+ -Data transformations
+- Re-parent a data structure
++ Re-parent a data structure
With
mergedata()
it is possible to wrap data containers inside of a new JSON data structure in the current namespace. @@ -15975,7 +16549,7 @@Re-parent a data structure
+R: { "pghba": [ { @@ -15990,8 +16564,8 @@Re-parent a data structure
- Merging a result from
+variablesmatching_as_data()
+ Merging a result from
variablesmatching_as_data()
I see. So, we need to merge the variable values together.
@@ -16062,7 +16636,7 @@Merging a result from
variablesmatching_as_data()
+R: merged: [ { "name": "check_ntp_time", @@ -16099,8 +16673,8 @@Merging a result from
variablesmatching_as_data()
- Inheriting calling bundles classes
++ Inheriting calling bundles classes
-bundle agent parent @@ -16136,8 +16710,8 @@-Inheriting calling bundles classes
R: Second see class parent_1 NOT defined- Bundles can return data
++ Bundles can return data
-bundle agent parent @@ -16166,8 +16740,8 @@-Bundles can return data
default:parent.my_returned_vars[msg] Hello world source=bundle- Tracking files for change (Tripwire/AIDE)
++ Tracking files for change (Tripwire/AIDE)
multiple ways of achieving this with CFEngine, there are many useful functions,
@@ -16240,7 +16814,7 @@lsdir()
,findfiles()
,filestat()
,file_hash()
all come to mind. However, did you know that CFEngine has some native functionality kind of like AIDE or Tripwire?Tracking files for change (Tripwire/AIDE)
+Resetting Observations CFEngine Core 3.17.0 CFEngine Enterprise 3.17.0 @@ -16362,7 +16936,7 @@Tracking files for change (Tripwire/AIDE)
+Resetting Observations CFEngine Core 3.17.0 CFEngine Enterprise 3.17.0 @@ -16529,7 +17103,7 @@Tracking files for change (Tripwire/AIDE)
+Resetting Observations CFEngine Core 3.17.0 CFEngine Enterprise 3.17.0 @@ -16586,25 +17160,25 @@Tracking files for change (Tripwire/AIDE)
- - Tips
++ -Tips
- Use the tools!
++ -Use the tools!
- Use an editor with syntax highlighting
++ -Use an editor with syntax highlighting
- Use the docs
++ -Use the docs
- Masterfiles Policy Framework (MPF)
- Function Reference
- Syntax Checking
++ -Syntax Checking
cf-promises --eval-functions=yes --full-check \ @@ -16650,8 +17224,8 @@-Syntax Checking
-- +
noshell
vsuseshell
forcommands
type promises,execresult()
, andreturnszero()
+
noshell
vsuseshell
forcommands
type promises,execresult()
, andreturnszero()
- Debug Reports
++ Debug Reports
Use standardized
@@ -16779,8 +17353,8 @@DEBUG
reports for policy development and troubleshooting.Debug Reports
- Promise comments
++ Promise comments
Use promise comments to document WHY the promise is important.
@@ -16799,8 +17373,8 @@Promise comments
- +
jq
+
jq
- +
cf-runagent
+
cf-runagent
cf-runagent --background=3 --remote-bundles satellite_registration \ @@ -16904,8 +17478,8 @@
cf-runagent
- - Additional Resources
++ Additional Resources
- CFEngine Build
- An index of CFEngine related content. Share your content and consume others!
- Learning CFEngine
- Widely considered best book to get a good grounding in CFEngine.
@@ -16953,25 +17527,25 @@Additional Resources
- - Wrapping up
++ Wrapping up
Please take a few moments to fill out this survey about your experience: https://www.surveymonkey.com/r/CFEngine-Training
- - Appendix
++ Appendix
- - Git Primer
++ -Git Primer
- Git
++ -Git
Git is the most popular modern version control management tool. Github, Bitbucket, and GitLab all provide great hosted and on prem repository management @@ -16993,13 +17567,13 @@
Git
- Getting started
++ -Getting started
Log into the policy server
-+[user@workstation] $ vagrant ssh hub [vagrant@hub] $ sudo -i@@ -17008,16 +17582,16 @@Getting started
Configure git author -+[root@hub masterfiles] # git config -–global user.name “Mr. Slate” [root@hub masterfiles] # git config -–global user.email “bossman@slateco.com” [root@hub masterfiles] # git config --global push.default simple- Clone builtin repository
-++ -Clone builtin repository
+[root@hub masterfiles] # git clone /opt/cfengine/masterfiles.git /vagrant/masterfiles Cloning into '/vagrant/masterfiles'...@@ -17032,9 +17606,9 @@Clone builtin repository
- Add a file to the repository
-++ -Add a file to the repository
+[root@hub masterfiles] # cd /vagrant/masterfiles [root@hub masterfiles] # ls cfe_internal Changelog controls def.cf lessons lib libraries promises.cf services sketches update update.cf @@ -17049,9 +17623,9 @@Add a file to the repository
- Stage and commit the changes
-++ -Stage and commit the changes
+[root@hub masterfiles] # git add file [root@hub masterfiles] # git status # On branch master @@ -17067,9 +17641,9 @@Stage and commit the changes
- Publish the change
-++ -Publish the change
+[root@hub masterfiles] # git status # On branch master # Your branch is ahead of 'origin/master' by 1 commit. @@ -17090,9 +17664,9 @@Publish the change
- Modify a file
-++ -Modify a file
+[root@hub masterfiles] # echo HI >> file [root@hub masterfiles] # git status # On branch master @@ -17108,9 +17682,9 @@Modify a file
- Diff to validate detail of content change
-++