Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
1266 commits
Select commit Hold shift + click to select a range
4761b89
Merge branch 'release-1.19.66'
aws-sdk-python-automation May 5, 2021
e7951a4
Merge branch 'release-1.19.67'
aws-sdk-python-automation May 5, 2021
b0ad49c
Merge branch 'release-1.19.68'
aws-sdk-python-automation May 6, 2021
ce4a17f
Merge branch 'release-1.19.69'
aws-sdk-python-automation May 7, 2021
97100c5
Merge branch 'release-1.19.70'
aws-sdk-python-automation May 10, 2021
e07715e
Merge branch 'release-1.19.71'
aws-sdk-python-automation May 11, 2021
fc9b714
Merge branch 'release-1.19.72'
aws-sdk-python-automation May 12, 2021
44d21c4
Merge branch 'release-1.19.73'
aws-sdk-python-automation May 14, 2021
2a5fabd
Merge branch 'release-1.19.74'
aws-sdk-python-automation May 17, 2021
6eb2196
Merge branch 'release-1.19.75'
aws-sdk-python-automation May 18, 2021
483d42b
Merge branch 'release-1.19.76'
aws-sdk-python-automation May 19, 2021
028182e
Merge branch 'release-1.19.77'
aws-sdk-python-automation May 20, 2021
de3ddf9
Merge branch 'release-1.19.78'
aws-sdk-python-automation May 21, 2021
5db80b6
Merge branch 'release-1.19.79'
aws-sdk-python-automation May 24, 2021
154a4e6
Merge branch 'release-1.19.80'
aws-sdk-python-automation May 25, 2021
c793669
Merge branch 'release-1.19.81'
aws-sdk-python-automation May 26, 2021
d9d0226
Merge branch 'release-1.19.82'
aws-sdk-python-automation May 27, 2021
e600b8d
Merge branch 'release-1.19.83'
aws-sdk-python-automation May 27, 2021
1f6a183
Merge branch 'release-1.19.84'
aws-sdk-python-automation May 28, 2021
86e226a
Merge branch 'release-1.19.85'
aws-sdk-python-automation Jun 1, 2021
eb77fd6
Merge branch 'release-1.19.86'
aws-sdk-python-automation Jun 2, 2021
73426af
Merge branch 'release-1.19.87'
aws-sdk-python-automation Jun 3, 2021
189bed0
Merge branch 'release-1.19.88'
aws-sdk-python-automation Jun 4, 2021
46ffa92
Merge branch 'release-1.19.89'
aws-sdk-python-automation Jun 7, 2021
26ddbed
Merge branch 'release-1.19.90'
aws-sdk-python-automation Jun 8, 2021
132d574
Merge branch 'release-1.19.91'
aws-sdk-python-automation Jun 9, 2021
f447790
Merge branch 'release-1.19.92'
aws-sdk-python-automation Jun 10, 2021
ddea4f2
Merge branch 'release-1.19.93'
aws-sdk-python-automation Jun 11, 2021
db0c1b8
Merge branch 'release-1.19.94'
aws-sdk-python-automation Jun 14, 2021
fd3238a
Merge branch 'release-1.19.95'
aws-sdk-python-automation Jun 15, 2021
62257ac
Merge branch 'release-1.19.96'
aws-sdk-python-automation Jun 16, 2021
4436e51
Merge branch 'release-1.19.97'
aws-sdk-python-automation Jun 17, 2021
0e39b92
Merge branch 'release-1.19.98'
aws-sdk-python-automation Jun 21, 2021
e7a7ab6
Merge branch 'release-1.19.99'
aws-sdk-python-automation Jun 23, 2021
28de390
Merge branch 'release-1.19.100'
aws-sdk-python-automation Jun 24, 2021
517f2f1
Merge branch 'release-1.19.101'
aws-sdk-python-automation Jun 25, 2021
3853d29
Merge branch 'release-1.19.102'
aws-sdk-python-automation Jun 28, 2021
992f1bb
Merge branch 'release-1.19.103'
aws-sdk-python-automation Jun 30, 2021
f557b41
Merge branch 'release-1.19.104'
aws-sdk-python-automation Jul 1, 2021
90780d8
Merge branch 'release-1.19.105'
aws-sdk-python-automation Jul 2, 2021
7ee6bb3
Merge branch 'release-1.19.106'
aws-sdk-python-automation Jul 6, 2021
a899f0b
Merge branch 'release-1.19.107'
aws-sdk-python-automation Jul 7, 2021
7a126d9
Merge branch 'release-1.19.108'
aws-sdk-python-automation Jul 8, 2021
0b94184
Merge branch 'release-1.19.109'
aws-sdk-python-automation Jul 9, 2021
c14a273
Merge branch 'release-1.19.110'
aws-sdk-python-automation Jul 12, 2021
57f5cfd
Merge branch 'release-1.19.111'
aws-sdk-python-automation Jul 13, 2021
d2613c6
Merge branch 'release-1.19.112'
aws-sdk-python-automation Jul 14, 2021
3ca7c31
Merge branch 'release-1.20.0'
aws-sdk-python-automation Jul 15, 2021
6a9bea8
Merge branch 'release-1.20.1'
aws-sdk-python-automation Jul 16, 2021
c3f4d5c
Merge branch 'release-1.20.2'
aws-sdk-python-automation Jul 19, 2021
28f7025
Merge branch 'release-1.20.3'
aws-sdk-python-automation Jul 20, 2021
ed64dde
Merge branch 'release-1.20.4'
aws-sdk-python-automation Jul 21, 2021
5899105
Merge branch 'release-1.20.5'
aws-sdk-python-automation Jul 22, 2021
3129a9a
Merge branch 'release-1.20.6'
aws-sdk-python-automation Jul 23, 2021
dc7047a
Merge branch 'release-1.20.7'
aws-sdk-python-automation Jul 26, 2021
01f1cdd
Merge branch 'release-1.20.8'
aws-sdk-python-automation Jul 27, 2021
b82ba41
Merge branch 'release-1.20.9'
aws-sdk-python-automation Jul 28, 2021
46d52a0
Merge branch 'release-1.20.10'
aws-sdk-python-automation Jul 29, 2021
a61f362
Merge branch 'release-1.20.11'
aws-sdk-python-automation Jul 30, 2021
9ade39a
Merge branch 'release-1.20.12'
aws-sdk-python-automation Aug 2, 2021
9127d20
Merge branch 'release-1.20.13'
aws-sdk-python-automation Aug 3, 2021
b8f8b42
Merge branch 'release-1.20.14'
aws-sdk-python-automation Aug 4, 2021
8f2df87
Merge branch 'release-1.20.15'
aws-sdk-python-automation Aug 5, 2021
c6306ce
Merge branch 'release-1.20.16'
aws-sdk-python-automation Aug 6, 2021
67727ee
Merge branch 'release-1.20.17'
aws-sdk-python-automation Aug 9, 2021
f549ad0
Merge branch 'release-1.20.18'
aws-sdk-python-automation Aug 10, 2021
8fa65cd
Merge branch 'release-1.20.19'
aws-sdk-python-automation Aug 11, 2021
d33bcc6
Merge branch 'release-1.20.20'
aws-sdk-python-automation Aug 12, 2021
c4fd548
Merge branch 'release-1.20.21'
aws-sdk-python-automation Aug 13, 2021
17b3bd8
Merge branch 'release-1.20.22'
aws-sdk-python-automation Aug 16, 2021
a959914
Merge branch 'release-1.20.23'
aws-sdk-python-automation Aug 17, 2021
570b2c1
Merge branch 'release-1.20.24'
aws-sdk-python-automation Aug 18, 2021
1a1f205
Merge branch 'release-1.20.25'
aws-sdk-python-automation Aug 19, 2021
8a02ca9
Merge branch 'release-1.20.26'
aws-sdk-python-automation Aug 20, 2021
63a3870
Merge branch 'release-1.20.27'
aws-sdk-python-automation Aug 23, 2021
02c9422
Merge branch 'release-1.20.28'
aws-sdk-python-automation Aug 24, 2021
8772d6d
Merge branch 'release-1.20.29'
aws-sdk-python-automation Aug 25, 2021
be110fa
Merge branch 'release-1.20.30'
aws-sdk-python-automation Aug 26, 2021
9fbc519
Merge branch 'release-1.20.31'
aws-sdk-python-automation Aug 27, 2021
560bbe8
Merge branch 'release-1.20.32'
aws-sdk-python-automation Aug 30, 2021
123c938
Merge branch 'release-1.20.33'
aws-sdk-python-automation Aug 31, 2021
62cbd3f
Merge branch 'release-1.20.34'
aws-sdk-python-automation Sep 1, 2021
268b957
Merge branch 'release-1.20.35'
aws-sdk-python-automation Sep 2, 2021
2fa2b17
Merge branch 'release-1.20.36'
aws-sdk-python-automation Sep 3, 2021
b7322a0
Merge branch 'release-1.20.37'
aws-sdk-python-automation Sep 7, 2021
d9b5159
Merge branch 'release-1.20.38'
aws-sdk-python-automation Sep 8, 2021
716276b
Merge branch 'release-1.20.39'
aws-sdk-python-automation Sep 9, 2021
aa192fb
Merge branch 'release-1.20.40'
aws-sdk-python-automation Sep 10, 2021
c23ecc2
Merge branch 'release-1.20.41'
aws-sdk-python-automation Sep 13, 2021
99cd22c
Merge branch 'release-1.20.42'
aws-sdk-python-automation Sep 14, 2021
6aa17da
Merge branch 'release-1.20.43'
aws-sdk-python-automation Sep 16, 2021
976a703
Merge branch 'release-1.20.44'
aws-sdk-python-automation Sep 17, 2021
67ee14a
Merge branch 'release-1.20.45'
aws-sdk-python-automation Sep 21, 2021
96a28ba
Merge branch 'release-1.20.46'
aws-sdk-python-automation Sep 22, 2021
16dc426
Merge branch 'release-1.20.47'
aws-sdk-python-automation Sep 23, 2021
b5e8e7f
Merge branch 'release-1.20.48'
aws-sdk-python-automation Sep 24, 2021
1121561
Merge branch 'release-1.20.49'
aws-sdk-python-automation Sep 27, 2021
f4023c2
Merge branch 'release-1.20.50'
aws-sdk-python-automation Sep 28, 2021
f2f5659
Merge branch 'release-1.20.51'
aws-sdk-python-automation Sep 29, 2021
8eab6f9
Merge branch 'release-1.20.52'
aws-sdk-python-automation Sep 30, 2021
fa0fd01
Merge branch 'release-1.20.53'
aws-sdk-python-automation Oct 1, 2021
bf9bb5b
Merge branch 'release-1.20.54'
aws-sdk-python-automation Oct 4, 2021
dce9cd1
Merge branch 'release-1.20.55'
aws-sdk-python-automation Oct 5, 2021
bee1a05
Merge branch 'release-1.20.56'
aws-sdk-python-automation Oct 6, 2021
c3a4fce
Merge branch 'release-1.20.57'
aws-sdk-python-automation Oct 7, 2021
ee47c94
Merge branch 'release-1.20.58'
aws-sdk-python-automation Oct 8, 2021
2603115
Merge branch 'release-1.20.59'
aws-sdk-python-automation Oct 11, 2021
f0bcc74
Merge branch 'release-1.20.60'
aws-sdk-python-automation Oct 12, 2021
0652f82
Merge branch 'release-1.20.61'
aws-sdk-python-automation Oct 13, 2021
fbbf1df
Merge branch 'release-1.20.62'
aws-sdk-python-automation Oct 14, 2021
7245c0e
Merge branch 'release-1.20.63'
aws-sdk-python-automation Oct 15, 2021
813edc6
Merge branch 'release-1.20.64'
aws-sdk-python-automation Oct 18, 2021
4a614b8
Merge branch 'release-1.20.65'
aws-sdk-python-automation Oct 19, 2021
723d5c9
Merge branch 'release-1.21.0'
aws-sdk-python-automation Oct 20, 2021
f4cc633
Merge branch 'release-1.21.1'
aws-sdk-python-automation Oct 21, 2021
a7b88c4
Merge branch 'release-1.21.2'
aws-sdk-python-automation Oct 22, 2021
db36d70
Merge branch 'release-1.21.3'
aws-sdk-python-automation Oct 25, 2021
8c83c4d
Merge branch 'release-1.21.4'
aws-sdk-python-automation Oct 26, 2021
6c8b86c
Merge branch 'release-1.21.5'
aws-sdk-python-automation Oct 27, 2021
86f2b0e
Merge branch 'release-1.21.6'
aws-sdk-python-automation Oct 28, 2021
1b03d0f
Merge branch 'release-1.21.7'
aws-sdk-python-automation Oct 29, 2021
31b358a
Merge branch 'release-1.21.8'
aws-sdk-python-automation Nov 1, 2021
1f834c6
Merge branch 'release-1.21.9'
aws-sdk-python-automation Nov 2, 2021
a74c818
Merge branch 'release-1.21.10'
aws-sdk-python-automation Nov 3, 2021
c2c63ce
Merge branch 'release-1.21.11'
aws-sdk-python-automation Nov 4, 2021
fac92af
Merge branch 'release-1.21.12'
aws-sdk-python-automation Nov 5, 2021
5153b46
Merge branch 'release-1.22.0'
aws-sdk-python-automation Nov 8, 2021
37195fc
Merge branch 'release-1.22.1'
aws-sdk-python-automation Nov 8, 2021
9a64de0
Merge branch 'release-1.22.2'
aws-sdk-python-automation Nov 9, 2021
8b1b9a8
Merge branch 'release-1.22.3'
aws-sdk-python-automation Nov 10, 2021
facf49e
Merge branch 'release-1.22.4'
aws-sdk-python-automation Nov 11, 2021
e3ffa5d
Merge branch 'release-1.22.5'
aws-sdk-python-automation Nov 12, 2021
77d1fc1
Merge branch 'release-1.22.6'
aws-sdk-python-automation Nov 15, 2021
dbc674a
Merge branch 'release-1.22.7'
aws-sdk-python-automation Nov 16, 2021
b6a5be4
Merge branch 'release-1.22.8'
aws-sdk-python-automation Nov 17, 2021
48bcb8c
Merge branch 'release-1.22.9'
aws-sdk-python-automation Nov 18, 2021
b3ffd6a
Merge branch 'release-1.22.10'
aws-sdk-python-automation Nov 19, 2021
b1021d2
Merge branch 'release-1.22.11'
aws-sdk-python-automation Nov 22, 2021
74cd099
Merge branch 'release-1.22.12'
aws-sdk-python-automation Nov 23, 2021
35d79bf
Merge branch 'release-1.22.13'
aws-sdk-python-automation Nov 24, 2021
e73bb8e
Merge branch 'release-1.22.14'
aws-sdk-python-automation Nov 26, 2021
6e3b330
Merge branch 'release-1.22.15'
aws-sdk-python-automation Nov 29, 2021
74aa2e3
Merge branch 'release-1.22.16'
aws-sdk-python-automation Nov 29, 2021
d8fc647
Merge branch 'release-1.22.17'
aws-sdk-python-automation Nov 30, 2021
56d4b38
Merge branch 'release-1.22.18'
aws-sdk-python-automation Dec 1, 2021
b11fe1d
Merge branch 'release-1.22.19'
aws-sdk-python-automation Dec 2, 2021
cd46cdb
Merge branch 'release-1.22.20'
aws-sdk-python-automation Dec 3, 2021
88bc1e0
Merge branch 'release-1.22.21'
aws-sdk-python-automation Dec 6, 2021
ca0b934
Merge branch 'release-1.22.22'
aws-sdk-python-automation Dec 8, 2021
46025a0
Merge branch 'release-1.22.23'
aws-sdk-python-automation Dec 9, 2021
8ba3de8
Merge branch 'release-1.22.24'
aws-sdk-python-automation Dec 13, 2021
52aa3ba
Merge branch 'release-1.22.25'
aws-sdk-python-automation Dec 20, 2021
eddb4f7
Merge branch 'release-1.22.26'
aws-sdk-python-automation Dec 21, 2021
55464cd
Merge branch 'release-1.22.27'
aws-sdk-python-automation Jan 3, 2022
a3e1a2a
Merge branch 'release-1.22.28'
aws-sdk-python-automation Jan 4, 2022
9ee8794
Merge branch 'release-1.22.29'
aws-sdk-python-automation Jan 5, 2022
56cd3d2
Merge branch 'release-1.22.30'
aws-sdk-python-automation Jan 6, 2022
bc0660a
Merge branch 'release-1.22.31'
aws-sdk-python-automation Jan 7, 2022
306089d
Merge branch 'release-1.22.32'
aws-sdk-python-automation Jan 10, 2022
dea638d
Merge branch 'release-1.22.33'
aws-sdk-python-automation Jan 11, 2022
4e357e3
Merge branch 'release-1.22.34'
aws-sdk-python-automation Jan 12, 2022
b1a4946
Merge branch 'release-1.22.35'
aws-sdk-python-automation Jan 13, 2022
0ffb009
Merge branch 'release-1.22.36'
aws-sdk-python-automation Jan 14, 2022
d0f133c
Merge branch 'release-1.22.37'
aws-sdk-python-automation Jan 15, 2022
2c43cbd
Merge branch 'release-1.22.38'
aws-sdk-python-automation Jan 18, 2022
c90a3a0
Merge branch 'release-1.22.39'
aws-sdk-python-automation Jan 19, 2022
9cdc7c3
Merge branch 'release-1.22.40'
aws-sdk-python-automation Jan 20, 2022
fa3f8a1
Merge branch 'release-1.22.41'
aws-sdk-python-automation Jan 21, 2022
34813ff
Merge branch 'release-1.22.42'
aws-sdk-python-automation Jan 24, 2022
3219450
Merge branch 'release-1.22.43'
aws-sdk-python-automation Jan 25, 2022
f41fc02
Merge branch 'release-1.22.44'
aws-sdk-python-automation Jan 26, 2022
4a58b87
Merge branch 'release-1.22.45'
aws-sdk-python-automation Jan 27, 2022
07c51e4
Merge branch 'release-1.22.46'
aws-sdk-python-automation Jan 28, 2022
bb43c56
Merge branch 'release-1.22.47'
aws-sdk-python-automation Feb 2, 2022
5976c68
Merge branch 'release-1.22.48'
aws-sdk-python-automation Feb 3, 2022
b1e8878
Merge branch 'release-1.22.49'
aws-sdk-python-automation Feb 4, 2022
b6e9764
Merge branch 'release-1.22.50'
aws-sdk-python-automation Feb 7, 2022
3919400
Merge branch 'release-1.22.51'
aws-sdk-python-automation Feb 8, 2022
89db5ea
Merge branch 'release-1.22.52'
aws-sdk-python-automation Feb 9, 2022
52e2ca2
Merge branch 'release-1.22.53'
aws-sdk-python-automation Feb 10, 2022
ba4accc
Merge branch 'release-1.22.54'
aws-sdk-python-automation Feb 11, 2022
6c16b14
Merge branch 'release-1.22.55'
aws-sdk-python-automation Feb 14, 2022
0a4baef
Merge branch 'release-1.22.56'
aws-sdk-python-automation Feb 16, 2022
1000956
Merge branch 'release-1.22.57'
aws-sdk-python-automation Feb 17, 2022
5160f01
Merge branch 'release-1.22.58'
aws-sdk-python-automation Feb 18, 2022
17a3fbb
Merge branch 'release-1.22.59'
aws-sdk-python-automation Feb 21, 2022
490e128
Merge branch 'release-1.22.60'
aws-sdk-python-automation Feb 22, 2022
9c5ae02
Merge branch 'release-1.22.61'
aws-sdk-python-automation Feb 23, 2022
efadea9
Merge branch 'release-1.22.62'
aws-sdk-python-automation Feb 24, 2022
77de650
Merge branch 'release-1.22.63'
aws-sdk-python-automation Feb 25, 2022
74770b7
Merge branch 'release-1.22.64'
aws-sdk-python-automation Feb 28, 2022
e5bdcf1
Merge branch 'release-1.22.65'
aws-sdk-python-automation Mar 1, 2022
ab613f2
Merge branch 'release-1.22.66'
aws-sdk-python-automation Mar 2, 2022
aeed389
Merge branch 'release-1.22.67'
aws-sdk-python-automation Mar 3, 2022
76ff8d9
Merge branch 'release-1.22.68'
aws-sdk-python-automation Mar 4, 2022
ee8c7e8
Merge branch 'release-1.22.69'
aws-sdk-python-automation Mar 7, 2022
188c58f
Merge branch 'release-1.22.70'
aws-sdk-python-automation Mar 8, 2022
7beb63d
Merge branch 'release-1.22.71'
aws-sdk-python-automation Mar 9, 2022
b434169
Merge branch 'release-1.22.72'
aws-sdk-python-automation Mar 10, 2022
1e8a329
Merge branch 'release-1.22.73'
aws-sdk-python-automation Mar 11, 2022
2fd3823
Merge branch 'release-1.22.74'
aws-sdk-python-automation Mar 14, 2022
becfc0c
Merge branch 'release-1.22.75'
aws-sdk-python-automation Mar 15, 2022
5c30d53
Merge branch 'release-1.22.76'
aws-sdk-python-automation Mar 16, 2022
b6bb5ab
Merge branch 'release-1.22.77'
aws-sdk-python-automation Mar 18, 2022
0f85352
Merge branch 'release-1.22.78'
aws-sdk-python-automation Mar 21, 2022
dae78a1
Merge branch 'release-1.22.79'
aws-sdk-python-automation Mar 22, 2022
f01a908
Merge branch 'release-1.22.80'
aws-sdk-python-automation Mar 23, 2022
2e99111
Merge branch 'release-1.22.81'
aws-sdk-python-automation Mar 24, 2022
b466f3d
Merge branch 'release-1.22.82'
aws-sdk-python-automation Mar 25, 2022
ba0618a
Merge branch 'release-1.22.83'
aws-sdk-python-automation Mar 28, 2022
57d3055
Merge branch 'release-1.22.84'
aws-sdk-python-automation Mar 29, 2022
cb8d9be
Merge branch 'release-1.22.85'
aws-sdk-python-automation Mar 30, 2022
47ee70c
Merge branch 'release-1.22.86'
aws-sdk-python-automation Mar 31, 2022
af85c6e
Merge branch 'release-1.22.87'
aws-sdk-python-automation Apr 1, 2022
be2a693
Merge branch 'release-1.22.88'
aws-sdk-python-automation Apr 4, 2022
19559b1
Merge branch 'release-1.22.89'
aws-sdk-python-automation Apr 5, 2022
4b7d616
Merge branch 'release-1.22.90'
aws-sdk-python-automation Apr 6, 2022
f15cf5f
Merge branch 'release-1.22.91'
aws-sdk-python-automation Apr 7, 2022
6f23701
Merge branch 'release-1.22.92'
aws-sdk-python-automation Apr 8, 2022
819f2a4
Merge branch 'release-1.22.93'
aws-sdk-python-automation Apr 11, 2022
6382ebf
Merge branch 'release-1.22.94'
aws-sdk-python-automation Apr 12, 2022
adf2380
Merge branch 'release-1.22.95'
aws-sdk-python-automation Apr 13, 2022
af3efaf
Merge branch 'release-1.22.96'
aws-sdk-python-automation Apr 14, 2022
8cfffd3
Merge branch 'release-1.22.97'
aws-sdk-python-automation Apr 15, 2022
83130db
Merge branch 'release-1.22.98'
aws-sdk-python-automation Apr 19, 2022
53d7b36
Merge branch 'release-1.22.99'
aws-sdk-python-automation Apr 20, 2022
0a6a563
Merge branch 'release-1.22.100'
aws-sdk-python-automation Apr 21, 2022
423249f
Merge branch 'release-1.22.101'
aws-sdk-python-automation Apr 22, 2022
edad847
Merge branch 'release-1.23.0'
aws-sdk-python-automation Apr 25, 2022
d3572db
Merge branch 'release-1.23.1'
aws-sdk-python-automation Apr 26, 2022
0b6949c
Merge branch 'release-1.23.2'
aws-sdk-python-automation Apr 27, 2022
882f8a6
Merge branch 'release-1.23.3'
aws-sdk-python-automation Apr 28, 2022
eeb12d8
Merge branch 'release-1.23.4'
aws-sdk-python-automation Apr 29, 2022
2644a6f
Merge branch 'release-1.23.5'
aws-sdk-python-automation May 2, 2022
5a43f8c
Merge branch 'release-1.23.6'
aws-sdk-python-automation May 3, 2022
a32597d
Merge branch 'release-1.23.7'
aws-sdk-python-automation May 4, 2022
34a823e
Merge branch 'release-1.23.8'
aws-sdk-python-automation May 5, 2022
2105789
Merge branch 'release-1.23.9'
aws-sdk-python-automation May 6, 2022
0432968
Merge branch 'release-1.23.10'
aws-sdk-python-automation May 9, 2022
0b6a3e5
Merge branch 'release-1.23.11'
aws-sdk-python-automation May 10, 2022
b1263fe
Merge branch 'release-1.23.12'
aws-sdk-python-automation May 11, 2022
884ad4d
add a functional test for "aws s3 sync" include/exclude
bugfood Apr 12, 2022
1e06fda
simplify test file path specification
bugfood Jul 28, 2020
375efe1
remove unused imports and variables from filegenerator unit test
bugfood Apr 13, 2022
b82c7b6
remove a couple unused local function assignments
bugfood Apr 12, 2022
bddaff9
autogenerate include-patterns for parent directories
bugfood Apr 13, 2022
81a2b75
s3.sync: Do not stat files that don't match filters
clarete Aug 13, 2016
26f85e6
test that excluded files are not examined
bugfood Apr 13, 2022
91723b6
add check that paths included are not intended to be excluded
bugfood May 12, 2022
0dccece
move all filtering to within the FileGenerator
bugfood May 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 30 additions & 7 deletions awscli/customizations/s3/filegenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from dateutil.tz import tzlocal
from botocore.exceptions import ClientError

from awscli.customizations.s3.fileinfo import FileInfo
from awscli.customizations.s3.utils import find_bucket_key, get_file_stat
from awscli.customizations.s3.utils import BucketLister, create_warning, \
find_dest_path_comp_key, EPOCH_TIME
Expand Down Expand Up @@ -116,7 +117,8 @@ class FileGenerator(object):
``FileInfo`` objects to send to a ``Comparator`` or ``S3Handler``.
"""
def __init__(self, client, operation_name, follow_symlinks=True,
page_size=None, result_queue=None, request_parameters=None):
page_size=None, result_queue=None, request_parameters=None,
file_filter=None):
self._client = client
self.operation_name = operation_name
self.follow_symlinks = follow_symlinks
Expand All @@ -127,6 +129,7 @@ def __init__(self, client, operation_name, follow_symlinks=True,
self.request_parameters = {}
if request_parameters is not None:
self.request_parameters = request_parameters
self.file_filter = file_filter

def call(self, files):
"""
Expand Down Expand Up @@ -168,8 +171,8 @@ def list_files(self, path, dir_op):
outputs. It yields the file's source path, size, and last
update
"""
join, isdir, isfile = os.path.join, os.path.isdir, os.path.isfile
error, listdir = os.error, os.listdir
join, isdir = os.path.join, os.path.isdir
listdir = os.listdir
if not self.should_ignore_file(path):
if not dir_op:
stats = self._safely_get_file_stats(path)
Expand Down Expand Up @@ -265,12 +268,18 @@ def should_ignore_file(self, path):
file generation process. This includes symlinks that are not to be
followed and files that generate warnings.
"""
if os.path.isdir(path) and path.endswith(os.sep):
# Trailing slash must be removed to check if it is a symlink.
# This also creates a normalized form for use in autogenerated
# parent-directory include filters.
path = path[:-1]
if not self.follow_symlinks:
if os.path.isdir(path) and path.endswith(os.sep):
# Trailing slash must be removed to check if it is a symlink.
path = path[:-1]
if os.path.islink(path):
return True
if self.file_filter is not None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we can move the file filter check into its own helper method that we could reuse across the local and s3 listing methods. So something like this:

def _should_ignore_from_file_filter(self, path):
      return (
           self.file_filter is None and
           not list(self.file_filter.call([FileInfo(path)]))
      )

This will make it a bit more reusable and improve readability as we are reducing the level of nesting/complexity in the if statements.

# We received a file_filter. Let's see if the path matches:
if not list(self.file_filter.call([FileInfo(path)])):
return True
warning_triggered = self.triggers_warning(path)
if warning_triggered:
return True
Expand Down Expand Up @@ -303,7 +312,21 @@ def triggers_warning(self, path):
return True
return False

def list_objects(self, s3_path, dir_op):
def list_objects(self, *args, **kwargs):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be great if we could consolidate the calls to the _list_objects_raw() to a single instance to help simplify the logic in list_objects():

def list_objects(self, s3_path, dir_op):
     for path, data in self._list_objects_raw(s3_path, dir_op):
         if self._should_ignore_from_file_filter(path):
             continue
         yield path, data

"""
Take unfiltered objects yielded by list_objects_raw() and return
only objects that pass through any filtering.
"""
if self.file_filter is None:
# With no filter, just pass data through.
yield from self.list_objects_raw(*args, **kwargs)
else:
# With a filter, check each path.
for path, data in self.list_objects_raw(*args, **kwargs):
if list(self.file_filter.call([FileInfo(path)])):
yield path, data

def list_objects_raw(self, s3_path, dir_op):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this method let's add an underscore to it to make it _list_objects_raw to indicate it's a private method and is only used within this class.

"""
This function yields the appropriate object or objects under a
common prefix depending if the operation is on objects under a
Expand Down
14 changes: 14 additions & 0 deletions awscli/customizations/s3/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ def _full_path_patterns(self, original_patterns, rootdir):
for pattern in original_patterns:
full_patterns.append(
(pattern[0], os.path.join(rootdir, pattern[1])))
# When including paths deep in the directory tree, auto-include the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still not sure I understand the case this logic is optimizing for after reading this comment: #5425 (comment) and the code. Would it be possible to illustrate the use/edge case with a sample directory structure and CLI commands? I think that would be really helpful.

In general, I'd prefer we do not change anything in the filters.py logic if we do not need to. Mainly the filters.py module is one of the older modules in the s3 package and we rarely update it. I think before adding any additional complexity to it, we do some refactoring of it to make it easier to follow/work with.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. I have to focus on another project for the time being, but I will circle back to this later for the technical changes requested.

I'm still not sure I understand the case this logic is optimizing for after reading this comment: #5425 (comment) and the code. Would it be possible to illustrate the use/edge case with a sample directory structure and CLI commands?

The use case is fairly simple:

aws s3 sync dir s3://bucket/dir '--exclude excluded/*' --include 'excluded/included/*'

If we make the FileGenerator no longer recurse into excluded directories, then excluded/included would never be examined and any files therein would have no chance to be included. What is needed is a specific include filter for excluded/included. We could make the user do it:

aws s3 sync dir s3://bucket/dir '--exclude excluded/*' --include excluded/included --include 'excluded/included/*'

...but that seems onerous and would break current behavior. In my PR, this is now verified by the commit with description add a functional test for "aws s3 sync" include/exclude.

The best solution I thought of was to auto-insert the necessary filter, since we know the existing filtering logic does what we need. I wanted to keep the special-case code to a minimum.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the detailed examples that was really helpful in understanding it! In general with this PR, we definitely need to make sure we do not break current behavior (i.e. given any set of filters + file set, the CLI will continue to include/exclude the same set of files after this change with no needing to adjust the filters provided at the command line).

While it looks like the coded that got added does handle the missing edge case that you illustrated, I am concerned that we are going to be missing other edge cases after seeing the edge case you raised. For example, suppose we had this directory layout:

$ tree .
.
├── directory
│   ├── another-dir
│   │   ├── exclude-me.txt
│   │   └── include-me.py
│   ├── exclude-me.txt
│   └── include-me.py
├── exclude-me.txt
└── include-me.py

If we only wanted to upload the .py files, a user would likely run a command like this:

$ aws s3 cp . s3://mybucket --recursive --exclude '*' --include '*.py' --dryrun

This would result in all of the .py files being uploaded:

(dryrun) upload: directory/another-dir/include-me.py to s3://mybucket/directory/another-dir/include-me.py
(dryrun) upload: directory/include-me.py to s3://mybucket/directory/include-me.py
(dryrun) upload: ./include-me.py to s3://mybucket/include-me.py

However, with the approach we are currently taking, we would still not traversing the directory and another-dir to get all of the .py files:

$ aws s3 cp . s3://mybucket --recursive --exclude '*' --include '*.py' --dryrun
(dryrun) upload: ./include-me.py to s3://mybucket/include-me.py

In general, I'm not optimistic the original approach of just applying the filters to the directory before traversing it is going to work. In terms of options to pursue, I think we either:

Thoughts? I want to think about this a bit more to see if I have any better suggestions, but I at least wanted to put this realization down now to start the discussion.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that is rough.

Your first idea seems best, but I don't know how to do that either.

A third idea would be to give the user control, either by a global option --no-traverse-excludes or a separate argument --hard-exclude <path> (to replace --exclude <path>). This isn't ideal, since it would be best if the program does the right thing automatically, but it may be more straightforward to implement and would not have unexpected consequences for current uses.

# parent directories. Otherwise, we may skip traversing into those
# parents due to an exclude.
if pattern[0] == 'include':
last_path = pattern[1]
while True:
parent = os.path.dirname(last_path)
if parent == last_path:
break
full_patterns.append(
('include', os.path.join(rootdir, parent)))

last_path = parent

return full_patterns

def call(self, file_infos):
Expand Down
12 changes: 5 additions & 7 deletions awscli/customizations/s3/subcommands.py
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,6 @@ def create_instructions(self):
"""
if self.needs_filegenerator():
self.instructions.append('file_generator')
if self.parameters.get('filters'):
self.instructions.append('filters')
if self.cmd == 'sync':
self.instructions.append('comparator')
self.instructions.append('file_info_builder')
Expand Down Expand Up @@ -976,17 +974,22 @@ def run(self):
result_queue = queue.Queue()
operation_name = cmd_translation[paths_type]

file_filter = (create_filter(self.parameters)
if 'filters' in self.parameters else None)

fgen_kwargs = {
'client': self._source_client, 'operation_name': operation_name,
'follow_symlinks': self.parameters['follow_symlinks'],
'page_size': self.parameters['page_size'],
'result_queue': result_queue,
'file_filter': file_filter,
}
rgen_kwargs = {
'client': self._client, 'operation_name': '',
'follow_symlinks': self.parameters['follow_symlinks'],
'page_size': self.parameters['page_size'],
'result_queue': result_queue,
'file_filter': file_filter,
}

fgen_request_parameters = \
Expand Down Expand Up @@ -1025,8 +1028,6 @@ def run(self):
command_dict = {'setup': [files, rev_files],
'file_generator': [file_generator,
rev_generator],
'filters': [create_filter(self.parameters),
create_filter(self.parameters)],
'comparator': [Comparator(**sync_strategies)],
'file_info_builder': [file_info_builder],
's3_handler': [s3_transfer_handler]}
Expand All @@ -1036,19 +1037,16 @@ def run(self):
elif self.cmd == 'cp':
command_dict = {'setup': [files],
'file_generator': [file_generator],
'filters': [create_filter(self.parameters)],
'file_info_builder': [file_info_builder],
's3_handler': [s3_transfer_handler]}
elif self.cmd == 'rm':
command_dict = {'setup': [files],
'file_generator': [file_generator],
'filters': [create_filter(self.parameters)],
'file_info_builder': [file_info_builder],
's3_handler': [s3_transfer_handler]}
elif self.cmd == 'mv':
command_dict = {'setup': [files],
'file_generator': [file_generator],
'filters': [create_filter(self.parameters)],
'file_info_builder': [file_info_builder],
's3_handler': [s3_transfer_handler]}

Expand Down
85 changes: 85 additions & 0 deletions tests/functional/s3/test_sync_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,91 @@ class TestSyncCommand(BaseS3TransferCommandTest):

prefix = 's3 sync '

def test_exclude_no_traverse(self):
"""Test that files within an excluded path are not examined during
directory traversal."""
path = os.path.join('excluded', 'foo')
full_path = self.files.create_file(path, 'mycontent')
# Use an unreadable file as a canary.
os.chmod(full_path, 0o000)

flags = [
"--only-show-errors",
"--exclude excluded/*",
]
cmdline = '%s %s %s s3://bucket/' % (
self.prefix, " ".join(flags), self.files.rootdir
)

self.run_cmd(cmdline, expected_rc=0)
# If this is unwriteable, then windows gets an error on os.unlink()
# during cleanup of the test dir.
os.chmod(full_path, 0o600)

def test_include_exclude(self):
"""Test the interaction of --include and --exclude. Filters specified
later override ones earlier."""
self.parsed_responses = [
# ListObjectsV2
{"CommonPrefixes": [], "Contents": []},
]
expected_ops = len(self.parsed_responses)

included = [
'included/foo',
'included/bar',
'excluded/included/foo',
'excluded/included/bar',
]
excluded = [
'excluded/foo',
'excluded/bar',
'included/excluded/foo',
'included/excluded/bar',
]
included = [path.replace('/', os.path.sep) for path in included]
excluded = [path.replace('/', os.path.sep) for path in excluded]

for file in included + excluded:
self.files.create_file(file, 'mycontent')
# Add a response for each potential file, even for files that
# should be excluded. Otherwise, if the exclusion fails to be
# applied, then the test will fail with a cryptic error when
# patch_make_request() fails to pop() a response. In that case,
# we'd rather have the test complete execution and then fail the
# assertions.
self.parsed_responses.append(
# PutObject
{'ETag': '"c8afdb36c52cf4727836669019e69222"'}
)

expected_ops += len(included)

flags = [
"--only-show-errors",
"--exclude excluded/*",
"--include excluded/included/*",
"--exclude included/excluded/*",
]
cmdline = '%s %s %s s3://bucket/' % (
self.prefix, " ".join(flags), self.files.rootdir
)

self.run_cmd(cmdline, expected_rc=0)

self.assertEqual(
len(self.operations_called),
expected_ops,
self.operations_called,
)

self.assertEqual(self.operations_called[0][0].name, 'ListObjectsV2')
for op in self.operations_called[1:]:
self.assertEqual(op[0].name, 'PutObject')
path = op[1]['Key'].replace('/', os.path.sep)
self.assertIn(path, included)
self.assertNotIn(path, excluded)

def test_website_redirect_ignore_paramfile(self):
full_path = self.files.create_file('foo.txt', 'mycontent')
cmdline = '%s %s s3://bucket/key.txt --website-redirect %s' % \
Expand Down
Loading